diff --git a/CHANGELOG.md b/CHANGELOG.md index 97d390c2..66e9afbe 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,8 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/). ## [Unreleased] +### Added +- Support text/uri-list attachments ([#355](https://github.com/cucumber/react-components/pull/355)) ## [22.2.0] - 2024-06-21 ### Added diff --git a/README.md b/README.md index 4760115b..4137e551 100644 --- a/README.md +++ b/README.md @@ -37,6 +37,17 @@ This is fine for simple use cases where results are not important. To render a `<GherkinDocument>` with results and highlighted [Cucumber Expression parameters](https://cucumber.io/docs/cucumber/cucumber-expressions/) parameters it must be nested inside a [`<Wrapper>`](src/components/app/Wrapper.tsx) component. +## Attachments + +Attachments from test runs are shown with their corresponding steps. The baseline behaviour for attachments is a download button. However, we have some special handling for very common MIME types to make them more useful without leaving the report: + +- `image/*` - images are rendered with an `<img/>` tag +- `video/*` - videos are rendered with a `<video/` tag +- `text/x.cucumber.log+plain` - logs (from calls to the `log` function in Cucumber) are rendered as monospace text, and support ANSI colors +- `text/uri-list` - one or more URLs are rendered as links that open in a new tab +- `application/json` - JSON is rendered as monospace text and prettified +- `text/*` - other text types are rendered as monospace text + ## Styling The standard styling comes from wrapping your top-level usage with the `CucumberReact` component (sans-props). There are several ways you can apply different styling to the components. diff --git a/package-lock.json b/package-lock.json index f9213af0..5872d538 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,9 +9,9 @@ "version": "22.2.0", "license": "MIT", "dependencies": { - "@cucumber/gherkin-utils": "8.0.6", - "@cucumber/messages": "24.0.1", - "@cucumber/query": "12.0.1", + "@cucumber/gherkin-utils": "9.0.0", + "@cucumber/messages": "25.0.1", + "@cucumber/query": "12.2.0", "@cucumber/tag-expressions": "6.1.0", "@fortawesome/fontawesome-svg-core": "6.2.1", "@fortawesome/free-solid-svg-icons": "6.2.1", @@ -35,8 +35,8 @@ "use-debounce": "^10.0.0" }, "devDependencies": { - "@cucumber/compatibility-kit": "15.0.0", - "@cucumber/fake-cucumber": "16.4.0", + "@cucumber/compatibility-kit": "16.1.0", + "@cucumber/fake-cucumber": "16.5.0", "@cucumber/gherkin": "28.0.0", "@cucumber/gherkin-streams": "5.0.1", "@cucumber/message-streams": "4.0.1", @@ -1874,38 +1874,42 @@ } }, "node_modules/@cucumber/ci-environment": { - "version": "9.0.4", - "resolved": "https://registry.npmjs.org/@cucumber/ci-environment/-/ci-environment-9.0.4.tgz", - "integrity": "sha512-da6H/wtVerhGUP4OCWTOmbNd4+gC1FhAcLzYgn6O68HgQbMwkmV3M8AwtbQWZkfF+Ph7z0M/UQYYdNIDu5V5MA==", - "dev": true + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/@cucumber/ci-environment/-/ci-environment-10.0.1.tgz", + "integrity": "sha512-/+ooDMPtKSmvcPMDYnMZt4LuoipfFfHaYspStI4shqw8FyKcfQAmekz6G+QKWjQQrvM+7Hkljwx58MEwPCwwzg==", + "dev": true, + "license": "MIT" }, "node_modules/@cucumber/compatibility-kit": { - "version": "15.0.0", - "resolved": "https://registry.npmjs.org/@cucumber/compatibility-kit/-/compatibility-kit-15.0.0.tgz", - "integrity": "sha512-5pzgNY0ylsQpcU0CxTBIRlo7+2F1helz/CUMbgE8E7IBxKVQ1czA/WgWtHoeVGm0i0zK5QE7TyDOUL5Nikek0Q==", - "dev": true + "version": "16.1.0", + "resolved": "https://registry.npmjs.org/@cucumber/compatibility-kit/-/compatibility-kit-16.1.0.tgz", + "integrity": "sha512-vzf5LKCBGvm7sHiuK4HOHYOChNazhSXMuD1s1Yc2i6xUsxHL23e+D+iXwpojGc4dSuz+xPSe/M+aLtwdfeXo3A==", + "dev": true, + "license": "MIT" }, "node_modules/@cucumber/cucumber-expressions": { - "version": "16.1.2", - "resolved": "https://registry.npmjs.org/@cucumber/cucumber-expressions/-/cucumber-expressions-16.1.2.tgz", - "integrity": "sha512-CfHEbxJ5FqBwF6mJyLLz4B353gyHkoi6cCL4J0lfDZ+GorpcWw4n2OUAdxJmP7ZlREANWoTFlp4FhmkLKrCfUA==", + "version": "17.1.0", + "resolved": "https://registry.npmjs.org/@cucumber/cucumber-expressions/-/cucumber-expressions-17.1.0.tgz", + "integrity": "sha512-PCv/ppsPynniKPWJr5v566daCVe+pbxQpHGrIu/Ev57cCH9Rv+X0F6lio4Id3Z64TaG7btCRLUGewIgLwmrwOA==", "dev": true, + "license": "MIT", "dependencies": { "regexp-match-indices": "1.0.2" } }, "node_modules/@cucumber/fake-cucumber": { - "version": "16.4.0", - "resolved": "https://registry.npmjs.org/@cucumber/fake-cucumber/-/fake-cucumber-16.4.0.tgz", - "integrity": "sha512-wBkirB5ha0hsN2GV5hQHwLJBJMImvemzIWgr/ah+bzZ1vsaHO/Qov903sZ3R5MiV8x6Nn4au7162VKi2AyX+PQ==", + "version": "16.5.0", + "resolved": "https://registry.npmjs.org/@cucumber/fake-cucumber/-/fake-cucumber-16.5.0.tgz", + "integrity": "sha512-Pr5BJZGDGVwwg0Bvpu+xebXI8B1S69hNACGDKwsXm0T52rcbrBUmA5X/BzorO3vDxyGBNwxc+ZPyRiocO3mZwg==", "dev": true, + "license": "MIT", "dependencies": { - "@cucumber/ci-environment": "^9.0.4", - "@cucumber/cucumber-expressions": "^16.0.0", + "@cucumber/ci-environment": "^10.0.0", + "@cucumber/cucumber-expressions": "^17.0.0", "@cucumber/tag-expressions": "^6.0.0", "@types/stack-utils": "2.0.3", - "commander": "11.1.0", - "glob": "10.3.10", + "commander": "12.1.0", + "glob": "10.4.5", "stack-utils": "2.0.6" }, "bin": { @@ -1924,15 +1928,17 @@ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", "dev": true, + "license": "MIT", "dependencies": { "balanced-match": "^1.0.0" } }, "node_modules/@cucumber/fake-cucumber/node_modules/foreground-child": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz", - "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==", + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.2.1.tgz", + "integrity": "sha512-PXUUyLqrR2XCWICfv6ukppP96sdFwWbNEnfEMt7jNsISjMsvaLNinAHNDYyvkyU+SZG2BTSbT5NjG+vZslfGTA==", "dev": true, + "license": "ISC", "dependencies": { "cross-spawn": "^7.0.0", "signal-exit": "^4.0.1" @@ -1945,32 +1951,32 @@ } }, "node_modules/@cucumber/fake-cucumber/node_modules/glob": { - "version": "10.3.10", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.10.tgz", - "integrity": "sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==", + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", "dev": true, + "license": "ISC", "dependencies": { "foreground-child": "^3.1.0", - "jackspeak": "^2.3.5", - "minimatch": "^9.0.1", - "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0", - "path-scurry": "^1.10.1" + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" }, "bin": { "glob": "dist/esm/bin.mjs" }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, "node_modules/@cucumber/fake-cucumber/node_modules/minimatch": { - "version": "9.0.3", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", - "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", "dev": true, + "license": "ISC", "dependencies": { "brace-expansion": "^2.0.1" }, @@ -1986,6 +1992,7 @@ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", "dev": true, + "license": "ISC", "engines": { "node": ">=14" }, @@ -1997,7 +2004,6 @@ "version": "28.0.0", "resolved": "https://registry.npmjs.org/@cucumber/gherkin/-/gherkin-28.0.0.tgz", "integrity": "sha512-Ee6zJQq0OmIUPdW0mSnsCsrWA2PZAELNDPICD2pLfs0Oz7RAPgj80UsD2UCtqyAhw2qAR62aqlktKUlai5zl/A==", - "dev": true, "dependencies": { "@cucumber/messages": ">=19.1.4 <=24" } @@ -2030,37 +2036,31 @@ } }, "node_modules/@cucumber/gherkin-utils": { - "version": "8.0.6", - "resolved": "https://registry.npmjs.org/@cucumber/gherkin-utils/-/gherkin-utils-8.0.6.tgz", - "integrity": "sha512-mtTXKJ5+yWTsMGf7gV7Q/57WpQHqzSgA8yMXzBalsSqLGaze+Pw+bPsHr077SBDLHuDn4o53tWrLMIRnQyJEmQ==", + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/@cucumber/gherkin-utils/-/gherkin-utils-9.0.0.tgz", + "integrity": "sha512-clk4q39uj7pztZuZtyI54V8lRsCUz0Y/p8XRjIeHh7ExeEztpWkp4ca9q1FjUOPfQQ8E7OgqFbqoQQXZ1Bx7fw==", + "license": "MIT", "dependencies": { - "@cucumber/gherkin": "^27.0.0", + "@cucumber/gherkin": "^28.0.0", "@cucumber/messages": "^24.0.0", "@teppeis/multimaps": "3.0.0", - "commander": "11.1.0", + "commander": "12.0.0", "source-map-support": "^0.5.21" }, "bin": { "gherkin-utils": "bin/gherkin-utils" } }, - "node_modules/@cucumber/gherkin-utils/node_modules/@cucumber/gherkin": { - "version": "27.0.0", - "resolved": "https://registry.npmjs.org/@cucumber/gherkin/-/gherkin-27.0.0.tgz", - "integrity": "sha512-j5rCsjqzRiC3iVTier3sa0kzyNbkcAmF7xr7jKnyO7qDeK3Z8Ye1P3KSVpeQRMY+KCDJ3WbTDdyxH0FwfA/fIw==", - "dependencies": { - "@cucumber/messages": ">=19.1.4 <=22" - } - }, - "node_modules/@cucumber/gherkin-utils/node_modules/@cucumber/gherkin/node_modules/@cucumber/messages": { - "version": "22.0.0", - "resolved": "https://registry.npmjs.org/@cucumber/messages/-/messages-22.0.0.tgz", - "integrity": "sha512-EuaUtYte9ilkxcKmfqGF9pJsHRUU0jwie5ukuZ/1NPTuHS1LxHPsGEODK17RPRbZHOFhqybNzG2rHAwThxEymg==", + "node_modules/@cucumber/gherkin-utils/node_modules/@cucumber/messages": { + "version": "24.1.0", + "resolved": "https://registry.npmjs.org/@cucumber/messages/-/messages-24.1.0.tgz", + "integrity": "sha512-hxVHiBurORcobhVk80I9+JkaKaNXkW6YwGOEFIh/2aO+apAN+5XJgUUWjng9NwqaQrW1sCFuawLB1AuzmBaNdQ==", + "license": "MIT", "dependencies": { - "@types/uuid": "9.0.1", + "@types/uuid": "9.0.8", "class-transformer": "0.5.1", - "reflect-metadata": "0.1.13", - "uuid": "9.0.0" + "reflect-metadata": "0.2.1", + "uuid": "9.0.1" } }, "node_modules/@cucumber/gherkin-utils/node_modules/@teppeis/multimaps": { @@ -2071,15 +2071,40 @@ "node": ">=14" } }, - "node_modules/@cucumber/gherkin-utils/node_modules/@types/uuid": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.1.tgz", - "integrity": "sha512-rFT3ak0/2trgvp4yYZo5iKFEPsET7vKydKF+VRCxlQ9bpheehyAJH89dAkaLEq/j/RZXJIqcgsmPJKUP1Z28HA==" + "node_modules/@cucumber/gherkin-utils/node_modules/commander": { + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-12.0.0.tgz", + "integrity": "sha512-MwVNWlYjDTtOjX5PiD7o5pK0UrFU/OYgcJfjjK4RaHZETNtjJqrZa9Y9ds88+A+f+d5lv+561eZ+yCKoS3gbAA==", + "license": "MIT", + "engines": { + "node": ">=18" + } }, "node_modules/@cucumber/gherkin-utils/node_modules/reflect-metadata": { - "version": "0.1.13", - "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.1.13.tgz", - "integrity": "sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg==" + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.2.1.tgz", + "integrity": "sha512-i5lLI6iw9AU3Uu4szRNPPEkomnkjRTaVt9hy/bn5g/oSzekBSMeLZblcjP74AW0vBabqERLLIrz+gR8QYR54Tw==", + "deprecated": "This version has a critical bug in fallback handling. Please upgrade to reflect-metadata@0.2.2 or newer.", + "license": "Apache-2.0" + }, + "node_modules/@cucumber/gherkin/node_modules/@cucumber/messages": { + "version": "24.1.0", + "resolved": "https://registry.npmjs.org/@cucumber/messages/-/messages-24.1.0.tgz", + "integrity": "sha512-hxVHiBurORcobhVk80I9+JkaKaNXkW6YwGOEFIh/2aO+apAN+5XJgUUWjng9NwqaQrW1sCFuawLB1AuzmBaNdQ==", + "license": "MIT", + "dependencies": { + "@types/uuid": "9.0.8", + "class-transformer": "0.5.1", + "reflect-metadata": "0.2.1", + "uuid": "9.0.1" + } + }, + "node_modules/@cucumber/gherkin/node_modules/reflect-metadata": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.2.1.tgz", + "integrity": "sha512-i5lLI6iw9AU3Uu4szRNPPEkomnkjRTaVt9hy/bn5g/oSzekBSMeLZblcjP74AW0vBabqERLLIrz+gR8QYR54Tw==", + "deprecated": "This version has a critical bug in fallback handling. Please upgrade to reflect-metadata@0.2.2 or newer.", + "license": "Apache-2.0" }, "node_modules/@cucumber/message-streams": { "version": "4.0.1", @@ -2091,45 +2116,54 @@ } }, "node_modules/@cucumber/messages": { - "version": "24.0.1", - "resolved": "https://registry.npmjs.org/@cucumber/messages/-/messages-24.0.1.tgz", - "integrity": "sha512-dKfNkvgc6stSQIyeHk7p/221iqEZe1BP+e/Js8XKtSmc0sS8khKMvbSBwYVeonn/67/vYKiAyo6Eo0SzXd5Plw==", + "version": "25.0.1", + "resolved": "https://registry.npmjs.org/@cucumber/messages/-/messages-25.0.1.tgz", + "integrity": "sha512-RjjhmzcauX5eYfcKns5pgenefDJQcfXE3ZDrVWdUDGcoaoyFVDmj+ZzQZWRWqFrfMjP3lKHJss6LtvIP/z+h8g==", + "license": "MIT", "dependencies": { - "@types/uuid": "9.0.7", + "@types/uuid": "9.0.8", "class-transformer": "0.5.1", - "reflect-metadata": "0.2.1", + "reflect-metadata": "0.2.2", "uuid": "9.0.1" } }, "node_modules/@cucumber/query": { - "version": "12.0.1", - "resolved": "https://registry.npmjs.org/@cucumber/query/-/query-12.0.1.tgz", - "integrity": "sha512-Dk6RGtzFRjylzp6N5jJOylIPxGr0pBr6KtHGTf/74RDFpx2FXpZJSPbEuXkLxtTUBiubVDfouH/oXbiZ17kTrQ==", + "version": "12.2.0", + "resolved": "https://registry.npmjs.org/@cucumber/query/-/query-12.2.0.tgz", + "integrity": "sha512-m+8Fl6VM1hdgCMorKoAIplHPiIThdoCwvzi48fkXw8BMDUVH1ZZ36qSwT1N+/4+Kkk0XIdy4A46P43UJL+j3iQ==", + "license": "MIT", "dependencies": { - "@cucumber/messages": "^19.1.4", - "@teppeis/multimaps": "2.0.0" + "@cucumber/messages": "^24.0.0", + "@teppeis/multimaps": "3.0.0" } }, "node_modules/@cucumber/query/node_modules/@cucumber/messages": { - "version": "19.1.4", - "resolved": "https://registry.npmjs.org/@cucumber/messages/-/messages-19.1.4.tgz", - "integrity": "sha512-Pksl0pnDz2l1+L5Ug85NlG6LWrrklN9qkMxN5Mv+1XZ3T6u580dnE6mVaxjJRdcOq4tR17Pc0RqIDZMyVY1FlA==", + "version": "24.1.0", + "resolved": "https://registry.npmjs.org/@cucumber/messages/-/messages-24.1.0.tgz", + "integrity": "sha512-hxVHiBurORcobhVk80I9+JkaKaNXkW6YwGOEFIh/2aO+apAN+5XJgUUWjng9NwqaQrW1sCFuawLB1AuzmBaNdQ==", + "license": "MIT", "dependencies": { - "@types/uuid": "8.3.4", + "@types/uuid": "9.0.8", "class-transformer": "0.5.1", - "reflect-metadata": "0.1.13", - "uuid": "9.0.0" + "reflect-metadata": "0.2.1", + "uuid": "9.0.1" } }, - "node_modules/@cucumber/query/node_modules/@types/uuid": { - "version": "8.3.4", - "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-8.3.4.tgz", - "integrity": "sha512-c/I8ZRb51j+pYGAu5CrFMRxqZ2ke4y2grEBO5AUjgSkSk+qT2Ea+OdWElz/OiMf5MNpn2b17kuVBwZLQJXzihw==" + "node_modules/@cucumber/query/node_modules/@teppeis/multimaps": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@teppeis/multimaps/-/multimaps-3.0.0.tgz", + "integrity": "sha512-ID7fosbc50TbT0MK0EG12O+gAP3W3Aa/Pz4DaTtQtEvlc9Odaqi0de+xuZ7Li2GtK4HzEX7IuRWS/JmZLksR3Q==", + "license": "MIT", + "engines": { + "node": ">=14" + } }, "node_modules/@cucumber/query/node_modules/reflect-metadata": { - "version": "0.1.13", - "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.1.13.tgz", - "integrity": "sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg==" + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.2.1.tgz", + "integrity": "sha512-i5lLI6iw9AU3Uu4szRNPPEkomnkjRTaVt9hy/bn5g/oSzekBSMeLZblcjP74AW0vBabqERLLIrz+gR8QYR54Tw==", + "deprecated": "This version has a critical bug in fallback handling. Please upgrade to reflect-metadata@0.2.2 or newer.", + "license": "Apache-2.0" }, "node_modules/@cucumber/tag-expressions": { "version": "6.1.0", @@ -2263,6 +2297,7 @@ "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", "dev": true, + "license": "ISC", "dependencies": { "string-width": "^5.1.2", "string-width-cjs": "npm:string-width@^4.2.0", @@ -2280,6 +2315,7 @@ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", "dev": true, + "license": "MIT", "engines": { "node": ">=12" }, @@ -2292,6 +2328,7 @@ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", "dev": true, + "license": "MIT", "engines": { "node": ">=12" }, @@ -2303,13 +2340,15 @@ "version": "9.2.2", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@isaacs/cliui/node_modules/string-width": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", "dev": true, + "license": "MIT", "dependencies": { "eastasianwidth": "^0.2.0", "emoji-regex": "^9.2.2", @@ -2327,6 +2366,7 @@ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", "dev": true, + "license": "MIT", "dependencies": { "ansi-regex": "^6.0.1" }, @@ -2342,6 +2382,7 @@ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", "dev": true, + "license": "MIT", "dependencies": { "ansi-styles": "^6.1.0", "string-width": "^5.0.1", @@ -2638,6 +2679,7 @@ "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", "dev": true, + "license": "MIT", "optional": true, "engines": { "node": ">=14" @@ -3062,9 +3104,10 @@ "integrity": "sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ==" }, "node_modules/@types/uuid": { - "version": "9.0.7", - "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.7.tgz", - "integrity": "sha512-WUtIVRUZ9i5dYXefDEAI7sh9/O7jGvHg7Df/5O/gtH3Yabe5odI3UWopVR1qbPXQtvOxWu3mM4XxlYeZtMWF4g==" + "version": "9.0.8", + "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.8.tgz", + "integrity": "sha512-jg+97EGIcY9AGHJJRaaPVgetKDsrTgbRjQ5Msgjh/DQKEFl0DtyRr/VCOyD1T2R1MNeWPK/u7JoGhlDZnKBAfA==", + "license": "MIT" }, "node_modules/@typescript-eslint/eslint-plugin": { "version": "5.48.1", @@ -4449,11 +4492,13 @@ } }, "node_modules/commander": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-11.1.0.tgz", - "integrity": "sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==", + "version": "12.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz", + "integrity": "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==", + "dev": true, + "license": "MIT", "engines": { - "node": ">=16" + "node": ">=18" } }, "node_modules/commondir": { @@ -7734,16 +7779,14 @@ } }, "node_modules/jackspeak": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.3.6.tgz", - "integrity": "sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==", + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", "dev": true, + "license": "BlueOak-1.0.0", "dependencies": { "@isaacs/cliui": "^8.0.2" }, - "engines": { - "node": ">=14" - }, "funding": { "url": "https://github.com/sponsors/isaacs" }, @@ -8652,10 +8695,11 @@ } }, "node_modules/minipass": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz", - "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==", + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", "dev": true, + "license": "ISC", "engines": { "node": ">=16 || 14 >=14.17" } @@ -9537,6 +9581,13 @@ "node": ">=8" } }, + "node_modules/package-json-from-dist": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.0.tgz", + "integrity": "sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw==", + "dev": true, + "license": "BlueOak-1.0.0" + }, "node_modules/parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", @@ -9638,29 +9689,28 @@ "dev": true }, "node_modules/path-scurry": { - "version": "1.10.1", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.1.tgz", - "integrity": "sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==", + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", "dev": true, + "license": "BlueOak-1.0.0", "dependencies": { - "lru-cache": "^9.1.1 || ^10.0.0", + "lru-cache": "^10.2.0", "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" }, "engines": { - "node": ">=16 || 14 >=14.17" + "node": ">=16 || 14 >=14.18" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, "node_modules/path-scurry/node_modules/lru-cache": { - "version": "10.2.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.2.0.tgz", - "integrity": "sha512-2bIM8x+VAf6JT4bKAljS1qUWgMsqZRPGJS6FSahIMPVvctcNhyVp7AJu7quxOW9jwkryBReKZY5tY5JYv2n/7Q==", + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", "dev": true, - "engines": { - "node": "14 || >=16.14" - } + "license": "ISC" }, "node_modules/path-to-regexp": { "version": "0.1.7", @@ -10382,9 +10432,10 @@ } }, "node_modules/reflect-metadata": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.2.1.tgz", - "integrity": "sha512-i5lLI6iw9AU3Uu4szRNPPEkomnkjRTaVt9hy/bn5g/oSzekBSMeLZblcjP74AW0vBabqERLLIrz+gR8QYR54Tw==" + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.2.2.tgz", + "integrity": "sha512-urBwgfrvVP/eAyXx4hluJivBKzuEbSQs9rKWCrCkbSxNv8mxPcUZKeuoF3Uy4mJl3Lwprp6yy5/39VWigZ4K6Q==", + "license": "Apache-2.0" }, "node_modules/regenerate": { "version": "1.4.2", @@ -10423,6 +10474,7 @@ "resolved": "https://registry.npmjs.org/regexp-match-indices/-/regexp-match-indices-1.0.2.tgz", "integrity": "sha512-DwZuAkt8NF5mKwGGER1EGh2PRqyvhRhhLviH+R8y8dIuaQROlUfXjt4s9ZTXstIsSkptf06BSvwcEmmfheJJWQ==", "dev": true, + "license": "Apache-2.0", "dependencies": { "regexp-tree": "^0.1.11" } @@ -10432,6 +10484,7 @@ "resolved": "https://registry.npmjs.org/regexp-tree/-/regexp-tree-0.1.27.tgz", "integrity": "sha512-iETxpjK6YoRWJG5o6hXLwvjYAoW+FEZn9os0PD/b6AP6xQwsa/Y7lCVgIixBbUPMfhu+i2LtdeAqVTgGlQarfA==", "dev": true, + "license": "MIT", "bin": { "regexp-tree": "bin/regexp-tree" } @@ -11362,6 +11415,7 @@ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, + "license": "MIT", "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -11453,6 +11507,7 @@ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, + "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" }, @@ -12680,6 +12735,7 @@ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "dev": true, + "license": "MIT", "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", @@ -12697,6 +12753,7 @@ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, + "license": "MIT", "dependencies": { "color-convert": "^2.0.1" }, diff --git a/package.json b/package.json index 8c95ee8c..8b88bff4 100644 --- a/package.json +++ b/package.json @@ -25,9 +25,9 @@ "pretty-quick-staged": "pretty-quick --staged" }, "dependencies": { - "@cucumber/gherkin-utils": "8.0.6", - "@cucumber/messages": "24.0.1", - "@cucumber/query": "12.0.1", + "@cucumber/gherkin-utils": "9.0.0", + "@cucumber/messages": "25.0.1", + "@cucumber/query": "12.2.0", "@cucumber/tag-expressions": "6.1.0", "@fortawesome/fontawesome-svg-core": "6.2.1", "@fortawesome/free-solid-svg-icons": "6.2.1", @@ -55,8 +55,8 @@ "react-dom": "~18" }, "devDependencies": { - "@cucumber/compatibility-kit": "15.0.0", - "@cucumber/fake-cucumber": "16.4.0", + "@cucumber/compatibility-kit": "16.1.0", + "@cucumber/fake-cucumber": "16.5.0", "@cucumber/gherkin": "28.0.0", "@cucumber/gherkin-streams": "5.0.1", "@cucumber/message-streams": "4.0.1", diff --git a/src/components/customise/customRendering.tsx b/src/components/customise/customRendering.tsx index 4a1a4c44..50195ffc 100644 --- a/src/components/customise/customRendering.tsx +++ b/src/components/customise/customRendering.tsx @@ -31,7 +31,7 @@ export interface AttachmentProps { attachment: messages.Attachment } -export type AttachmentClasses = Styles<'text' | 'log' | 'icon' | 'image'> +export type AttachmentClasses = Styles<'text' | 'log' | 'icon' | 'image' | 'links'> export interface BackgroundProps { background: messages.Background diff --git a/src/components/gherkin/attachment/Attachment.module.scss b/src/components/gherkin/attachment/Attachment.module.scss index 8310ea6f..8e2a7cec 100644 --- a/src/components/gherkin/attachment/Attachment.module.scss +++ b/src/components/gherkin/attachment/Attachment.module.scss @@ -37,3 +37,21 @@ max-width: 100%; margin-top: 0.5em; } + +.links { + list-style: none; + display: flex; + flex-direction: column; + align-items: flex-start; + padding: 0; + margin: 0; + + a { + text-decoration: none; + color: $anchorColor; + } + + svg { + margin-right: 0.5em; + } +} \ No newline at end of file diff --git a/src/components/gherkin/attachment/Attachment.spec.tsx b/src/components/gherkin/attachment/Attachment.spec.tsx index 41fce80e..d1f6927d 100644 --- a/src/components/gherkin/attachment/Attachment.spec.tsx +++ b/src/components/gherkin/attachment/Attachment.spec.tsx @@ -166,4 +166,41 @@ describe('<Attachment>', () => { '<span style="color:#000">black<span style="color:#AAA">white</span></span>' ) }) + + it('renders a link', () => { + const attachment: messages.Attachment = { + mediaType: 'text/uri-list', + contentEncoding: AttachmentContentEncoding.IDENTITY, + body: 'https://cucumber.io', + } + + render(<Attachment attachment={attachment} />) + + expect(screen.getByRole('link', { name: 'https://cucumber.io' })).to.be.visible + expect(screen.getByRole('link', { name: 'https://cucumber.io' })).to.have.attr( + 'href', + 'https://cucumber.io' + ) + }) + + it('renders multiple links and ignores blank lines', () => { + const attachment: messages.Attachment = { + mediaType: 'text/uri-list', + contentEncoding: AttachmentContentEncoding.IDENTITY, + body: `https://github.com/cucumber/cucumber-js +https://github.com/cucumber/cucumber-jvm +https://github.com/cucumber/cucumber-ruby +`, + } + + render(<Attachment attachment={attachment} />) + + expect(screen.getAllByRole('link').length).to.eq(3) + expect(screen.getByRole('link', { name: 'https://github.com/cucumber/cucumber-js' })).to.be + .visible + expect(screen.getByRole('link', { name: 'https://github.com/cucumber/cucumber-jvm' })).to.be + .visible + expect(screen.getByRole('link', { name: 'https://github.com/cucumber/cucumber-ruby' })).to.be + .visible + }) }) diff --git a/src/components/gherkin/attachment/Attachment.stories.tsx b/src/components/gherkin/attachment/Attachment.stories.tsx index 32b719c4..5add243b 100644 --- a/src/components/gherkin/attachment/Attachment.stories.tsx +++ b/src/components/gherkin/attachment/Attachment.stories.tsx @@ -33,6 +33,26 @@ Log.args = { }, } satisfies AttachmentProps +export const Link = Template.bind({}) +Link.args = { + attachment: { + mediaType: 'text/uri-list', + contentEncoding: AttachmentContentEncoding.IDENTITY, + body: 'https://cucumber.io', + }, +} satisfies AttachmentProps + +export const MultipleLinks = Template.bind({}) +MultipleLinks.args = { + attachment: { + mediaType: 'text/uri-list', + contentEncoding: AttachmentContentEncoding.IDENTITY, + body: `https://github.com/cucumber/cucumber-js +https://github.com/cucumber/cucumber-jvm +https://github.com/cucumber/cucumber-ruby`, + }, +} satisfies AttachmentProps + export const ExternalisedImage = Template.bind({}) ExternalisedImage.storyName = 'Externalised image' ExternalisedImage.args = { diff --git a/src/components/gherkin/attachment/Attachment.tsx b/src/components/gherkin/attachment/Attachment.tsx index e7fe653f..32c9bfb7 100644 --- a/src/components/gherkin/attachment/Attachment.tsx +++ b/src/components/gherkin/attachment/Attachment.tsx @@ -10,6 +10,7 @@ import { import { ErrorMessage } from '../ErrorMessage.js' import defaultStyles from './Attachment.module.scss' import { Image } from './Image.js' +import { Links } from './Links.js' import { Log } from './Log.js' import { Text } from './Text.js' import { Unknown } from './Unknown.js' @@ -25,6 +26,8 @@ const DefaultRenderer: DefaultComponent<AttachmentProps, AttachmentClasses> = ({ return <Video attachment={attachment} /> } else if (attachment.mediaType == 'text/x.cucumber.log+plain') { return <Log attachment={attachment} classes={styles} /> + } else if (attachment.mediaType == 'text/uri-list') { + return <Links attachment={attachment} classes={styles} /> } else if (attachment.mediaType.match(/^text\//)) { return <Text attachment={attachment} classes={styles} /> } else if (attachment.mediaType.match(/^application\/json/)) { diff --git a/src/components/gherkin/attachment/Links.tsx b/src/components/gherkin/attachment/Links.tsx new file mode 100644 index 00000000..551a115a --- /dev/null +++ b/src/components/gherkin/attachment/Links.tsx @@ -0,0 +1,31 @@ +import { Attachment } from '@cucumber/messages' +import { faLink } from '@fortawesome/free-solid-svg-icons' +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' +import React, { FC } from 'react' + +import { AttachmentClasses } from '../../customise/index.js' +import { useText } from './useText.js' + +export const Links: FC<{ + attachment: Attachment + classes: AttachmentClasses +}> = ({ attachment, classes }) => { + const { content } = useText(attachment) + return ( + <ul className={classes.links}> + {content + .split('\n') + .filter((line) => !!line) + .map((line, index) => { + return ( + <li key={index}> + <a href={line} target="_blank" rel="noreferrer"> + <FontAwesomeIcon icon={faLink} /> + {line} + </a> + </li> + ) + })} + </ul> + ) +}