happo 6.0.0-beta.3 → 6.0.0-beta.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +10 -17
- package/dist/cli/{cancelJob-URIFHFSY.js → cancelJob-BTQFKZIA.js} +3 -3
- package/dist/cli/{createAsyncComparison-L7GSHG7G.js → chunk-Q6MYY7SZ.js} +9 -4
- package/dist/cli/chunk-Q6MYY7SZ.js.map +7 -0
- package/dist/cli/{chunk-CJCPD3BP.js → chunk-RQIPXFYO.js} +9 -8
- package/dist/cli/chunk-RQIPXFYO.js.map +7 -0
- package/dist/cli/{chunk-JUHWFN2G.js → chunk-RRBBL3EW.js} +2 -2
- package/dist/cli/createAsyncComparison-IWILXO74.js +9 -0
- package/dist/cli/{createAsyncReport-L5QAKXE7.js → createAsyncReport-IROUZ4HE.js} +3 -3
- package/dist/cli/index.js +23 -18
- package/dist/cli/index.js.map +2 -2
- package/dist/cli/package-Z7RTWGGQ.js +7 -0
- package/dist/cli/package-Z7RTWGGQ.js.map +7 -0
- package/dist/cli/{prepareSnapRequests-Z2OGZ3NF.js → prepareSnapRequests-ULZ2RJ6S.js} +57 -44
- package/dist/cli/prepareSnapRequests-ULZ2RJ6S.js.map +7 -0
- package/dist/cli/{startJob-TMQQTP56.js → startJob-5B6M5C6Y.js} +3 -3
- package/dist/cli/{wrapper-2EC762P2.js → wrapper-ISNKAWC2.js} +44 -82
- package/dist/cli/wrapper-ISNKAWC2.js.map +7 -0
- package/dist/config/RemoteBrowserTarget.d.ts +6 -11
- package/dist/config/RemoteBrowserTarget.d.ts.map +1 -1
- package/dist/config/index.d.ts +20 -12
- package/dist/config/index.d.ts.map +1 -1
- package/dist/config/index.js.map +2 -2
- package/dist/{static → custom}/__happo__/index.d.ts.map +1 -1
- package/dist/{static → custom}/index.d.ts.map +1 -1
- package/dist/{static → custom}/index.js +1 -1
- package/dist/{static → custom}/index.js.map +1 -1
- package/dist/cypress/task.js +20 -34
- package/dist/cypress/task.js.map +2 -2
- package/dist/e2e/controller.d.ts +1 -1
- package/dist/e2e/controller.d.ts.map +1 -1
- package/dist/e2e/wrapper.d.ts.map +1 -1
- package/dist/environment/index.d.ts +1 -1
- package/dist/environment/index.d.ts.map +1 -1
- package/dist/network/createAsyncComparison.d.ts.map +1 -1
- package/dist/network/prepareSnapRequests.d.ts.map +1 -1
- package/dist/playwright/index.js +20 -34
- package/dist/playwright/index.js.map +2 -2
- package/dist/storybook/index.d.ts +1 -1
- package/dist/storybook/index.d.ts.map +1 -1
- package/dist/storybook/index.js +2 -2
- package/dist/storybook/index.js.map +2 -2
- package/package.json +8 -7
- package/dist/cli/chunk-CJCPD3BP.js.map +0 -7
- package/dist/cli/createAsyncComparison-L7GSHG7G.js.map +0 -7
- package/dist/cli/package-TEFLJOJ3.js +0 -7
- package/dist/cli/prepareSnapRequests-Z2OGZ3NF.js.map +0 -7
- package/dist/cli/wrapper-2EC762P2.js.map +0 -7
- /package/dist/cli/{cancelJob-URIFHFSY.js.map → cancelJob-BTQFKZIA.js.map} +0 -0
- /package/dist/cli/{chunk-JUHWFN2G.js.map → chunk-RRBBL3EW.js.map} +0 -0
- /package/dist/cli/{package-TEFLJOJ3.js.map → createAsyncComparison-IWILXO74.js.map} +0 -0
- /package/dist/cli/{createAsyncReport-L5QAKXE7.js.map → createAsyncReport-IROUZ4HE.js.map} +0 -0
- /package/dist/cli/{startJob-TMQQTP56.js.map → startJob-5B6M5C6Y.js.map} +0 -0
- /package/dist/{static → custom}/__happo__/index.d.ts +0 -0
- /package/dist/{static → custom}/index.d.ts +0 -0
package/README.md
CHANGED
|
@@ -18,7 +18,6 @@ For comprehensive documentation, visit [docs.happo.io](https://docs.happo.io).
|
|
|
18
18
|
- **Flexible Configuration**: Support for multiple configuration file formats
|
|
19
19
|
- **TypeScript Support**: Built with TypeScript and provides full type definitions
|
|
20
20
|
- **ES Modules**: Uses modern ES modules for better tree-shaking and performance
|
|
21
|
-
- **Cross-Platform**: Works on all major operating systems
|
|
22
21
|
|
|
23
22
|
## 📦 Installation
|
|
24
23
|
|
|
@@ -44,15 +43,15 @@ export default defineConfig({
|
|
|
44
43
|
apiSecret: process.env.HAPPO_API_SECRET!,
|
|
45
44
|
targets: {
|
|
46
45
|
'chrome-desktop': {
|
|
47
|
-
|
|
46
|
+
type: 'chrome',
|
|
48
47
|
viewport: '1280x720',
|
|
49
48
|
},
|
|
50
49
|
'firefox-desktop': {
|
|
51
|
-
|
|
50
|
+
type: 'firefox',
|
|
52
51
|
viewport: '1280x720',
|
|
53
52
|
},
|
|
54
53
|
'ios-safari': {
|
|
55
|
-
|
|
54
|
+
type: 'ios-safari',
|
|
56
55
|
},
|
|
57
56
|
},
|
|
58
57
|
});
|
|
@@ -66,7 +65,7 @@ Run Happo using the CLI:
|
|
|
66
65
|
npx happo
|
|
67
66
|
```
|
|
68
67
|
|
|
69
|
-
The CLI will automatically find your configuration file and
|
|
68
|
+
The CLI will automatically find your configuration file and run the visual regression test suite.
|
|
70
69
|
|
|
71
70
|
## 🔧 Configuration Options
|
|
72
71
|
|
|
@@ -84,8 +83,9 @@ The library automatically detects configuration files in the following order:
|
|
|
84
83
|
### Key Configuration Properties
|
|
85
84
|
|
|
86
85
|
- **`apiKey`** & **`apiSecret`**: Authentication credentials for happo.io
|
|
87
|
-
- **`
|
|
88
|
-
- **`
|
|
86
|
+
- **`integration`**: Set up the integration type
|
|
87
|
+
- **`targets`**: Target configurations, including regular browsers and accessibility targets
|
|
88
|
+
- **`project`**: Optional project name
|
|
89
89
|
|
|
90
90
|
### Browser Targets
|
|
91
91
|
|
|
@@ -97,16 +97,9 @@ Supported browser types:
|
|
|
97
97
|
Each target supports advanced options like:
|
|
98
98
|
|
|
99
99
|
- Viewport sizing
|
|
100
|
-
- Maximum
|
|
100
|
+
- Maximum dimensions
|
|
101
101
|
- Color scheme preferences
|
|
102
|
-
|
|
103
|
-
## 🧪 Testing
|
|
104
|
-
|
|
105
|
-
This project uses Node.js built-in test runner:
|
|
106
|
-
|
|
107
|
-
```bash
|
|
108
|
-
npm test
|
|
109
|
-
```
|
|
102
|
+
- Settings for silencing animations
|
|
110
103
|
|
|
111
104
|
## 🤝 Contributing
|
|
112
105
|
|
|
@@ -117,7 +110,7 @@ Pull requests are welcome! For major changes, please open an issue first to disc
|
|
|
117
110
|
1. Clone the repository
|
|
118
111
|
2. Install dependencies: `pnpm install`
|
|
119
112
|
3. Build the project: `pnpm build`
|
|
120
|
-
4. Run tests
|
|
113
|
+
4. Run all tests and checks: `pnpm all`
|
|
121
114
|
|
|
122
115
|
To run the tests you will need a `.env.local` file with some keys. Use
|
|
123
116
|
`env.example` as a starting point.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
makeHappoAPIRequest
|
|
3
|
-
} from "./chunk-
|
|
4
|
-
import "./chunk-
|
|
3
|
+
} from "./chunk-RRBBL3EW.js";
|
|
4
|
+
import "./chunk-RQIPXFYO.js";
|
|
5
5
|
|
|
6
6
|
// src/network/cancelJob.ts
|
|
7
7
|
async function cancelJob(status, config, { beforeSha, afterSha, link, message }, logger) {
|
|
@@ -24,4 +24,4 @@ async function cancelJob(status, config, { beforeSha, afterSha, link, message },
|
|
|
24
24
|
export {
|
|
25
25
|
cancelJob as default
|
|
26
26
|
};
|
|
27
|
-
//# sourceMappingURL=cancelJob-
|
|
27
|
+
//# sourceMappingURL=cancelJob-BTQFKZIA.js.map
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
makeHappoAPIRequest
|
|
3
|
-
} from "./chunk-
|
|
4
|
-
import "./chunk-CJCPD3BP.js";
|
|
3
|
+
} from "./chunk-RRBBL3EW.js";
|
|
5
4
|
|
|
6
5
|
// src/network/createAsyncComparison.ts
|
|
7
6
|
function assertResultIsCreateAsyncComparisonResult(result) {
|
|
@@ -27,6 +26,11 @@ async function createAsyncComparison(config, {
|
|
|
27
26
|
notify,
|
|
28
27
|
fallbackShas
|
|
29
28
|
}, logger) {
|
|
29
|
+
if (beforeSha === afterSha) {
|
|
30
|
+
throw new Error(
|
|
31
|
+
`Cannot create an async comparison between the same SHA (beforeSha=${beforeSha}, afterSha=${afterSha})`
|
|
32
|
+
);
|
|
33
|
+
}
|
|
30
34
|
const result = await makeHappoAPIRequest(
|
|
31
35
|
{
|
|
32
36
|
path: `/api/reports/${beforeSha}/compare/${afterSha}`,
|
|
@@ -48,7 +52,8 @@ async function createAsyncComparison(config, {
|
|
|
48
52
|
assertResultIsCreateAsyncComparisonResult(result);
|
|
49
53
|
return result;
|
|
50
54
|
}
|
|
55
|
+
|
|
51
56
|
export {
|
|
52
|
-
createAsyncComparison
|
|
57
|
+
createAsyncComparison
|
|
53
58
|
};
|
|
54
|
-
//# sourceMappingURL=
|
|
59
|
+
//# sourceMappingURL=chunk-Q6MYY7SZ.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/network/createAsyncComparison.ts"],
|
|
4
|
+
"sourcesContent": ["import type { ConfigWithDefaults } from '../config/index.ts';\nimport type { EnvironmentResult } from '../environment/index.ts';\nimport type { Logger } from '../isomorphic/types.ts';\nimport makeHappoAPIRequest from './makeHappoAPIRequest.ts';\n\ninterface CreateAsyncComparisonResult {\n id: number;\n statusImageUrl: string;\n compareUrl: string;\n}\n\nfunction assertResultIsCreateAsyncComparisonResult(\n result: unknown,\n): asserts result is CreateAsyncComparisonResult {\n if (typeof result !== 'object' || result === null) {\n throw new TypeError('Result is not an object');\n }\n\n if (!('id' in result) || typeof result.id !== 'number') {\n throw new TypeError('Result is missing id');\n }\n\n if (!('statusImageUrl' in result) || typeof result.statusImageUrl !== 'string') {\n throw new TypeError('Result is missing statusImageUrl');\n }\n\n if (!('compareUrl' in result) || typeof result.compareUrl !== 'string') {\n throw new TypeError('Result is missing compareUrl');\n }\n}\n\n/**\n * Create an async comparison between two SHAs\n *\n * @see https://happo.io/docs/api#compareReports\n */\nexport default async function createAsyncComparison(\n config: ConfigWithDefaults,\n {\n beforeSha,\n afterSha,\n link,\n message,\n author,\n notify,\n fallbackShas,\n }: EnvironmentResult,\n logger: Logger,\n): Promise<CreateAsyncComparisonResult> {\n if (beforeSha === afterSha) {\n throw new Error(\n `Cannot create an async comparison between the same SHA (beforeSha=${beforeSha}, afterSha=${afterSha})`,\n );\n }\n\n const result = await makeHappoAPIRequest(\n {\n path: `/api/reports/${beforeSha}/compare/${afterSha}`,\n method: 'POST',\n body: {\n link,\n message,\n author,\n project: config.project,\n isAsync: true,\n notify,\n fallbackShas,\n },\n },\n config,\n { retryCount: 3 },\n logger,\n );\n\n assertResultIsCreateAsyncComparisonResult(result);\n\n return result;\n}\n"],
|
|
5
|
+
"mappings": ";;;;;AAWA,SAAS,0CACP,QAC+C;AAC/C,MAAI,OAAO,WAAW,YAAY,WAAW,MAAM;AACjD,UAAM,IAAI,UAAU,yBAAyB;AAAA,EAC/C;AAEA,MAAI,EAAE,QAAQ,WAAW,OAAO,OAAO,OAAO,UAAU;AACtD,UAAM,IAAI,UAAU,sBAAsB;AAAA,EAC5C;AAEA,MAAI,EAAE,oBAAoB,WAAW,OAAO,OAAO,mBAAmB,UAAU;AAC9E,UAAM,IAAI,UAAU,kCAAkC;AAAA,EACxD;AAEA,MAAI,EAAE,gBAAgB,WAAW,OAAO,OAAO,eAAe,UAAU;AACtE,UAAM,IAAI,UAAU,8BAA8B;AAAA,EACpD;AACF;AAOA,eAAO,sBACL,QACA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GACA,QACsC;AACtC,MAAI,cAAc,UAAU;AAC1B,UAAM,IAAI;AAAA,MACR,qEAAqE,SAAS,cAAc,QAAQ;AAAA,IACtG;AAAA,EACF;AAEA,QAAM,SAAS,MAAM;AAAA,IACnB;AAAA,MACE,MAAM,gBAAgB,SAAS,YAAY,QAAQ;AAAA,MACnD,QAAQ;AAAA,MACR,MAAM;AAAA,QACJ;AAAA,QACA;AAAA,QACA;AAAA,QACA,SAAS,OAAO;AAAA,QAChB,SAAS;AAAA,QACT;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,IACA;AAAA,IACA,EAAE,YAAY,EAAE;AAAA,IAChB;AAAA,EACF;AAEA,4CAA0C,MAAM;AAEhD,SAAO;AACT;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// package.json
|
|
2
2
|
var package_default = {
|
|
3
3
|
name: "happo",
|
|
4
|
-
version: "6.0.0-beta.
|
|
4
|
+
version: "6.0.0-beta.5",
|
|
5
5
|
description: "Visual regression testing and accessibility testing",
|
|
6
6
|
license: "MIT",
|
|
7
7
|
repository: {
|
|
@@ -33,9 +33,9 @@ var package_default = {
|
|
|
33
33
|
types: "./dist/playwright/index.d.ts",
|
|
34
34
|
default: "./dist/playwright/index.js"
|
|
35
35
|
},
|
|
36
|
-
"./
|
|
37
|
-
types: "./dist/
|
|
38
|
-
default: "./dist/
|
|
36
|
+
"./custom": {
|
|
37
|
+
types: "./dist/custom/index.d.ts",
|
|
38
|
+
default: "./dist/custom/index.js"
|
|
39
39
|
},
|
|
40
40
|
"./storybook/addon": {
|
|
41
41
|
types: "./dist/storybook/browser/addon.d.ts",
|
|
@@ -60,20 +60,21 @@ var package_default = {
|
|
|
60
60
|
scripts: {
|
|
61
61
|
all: "node ./scripts/allchecks.ts",
|
|
62
62
|
build: "pnpm build:types && pnpm build:dist",
|
|
63
|
+
"build:custom": "esbuild src/custom/__happo__/index.ts --bundle --format=iife --global-name=happoCustom --outfile=tmp/happo-custom/bundle.js --platform=browser --target=esnext",
|
|
63
64
|
"build:dist": "./scripts/build.ts",
|
|
64
65
|
"build:types": "pnpm tsc --pretty",
|
|
65
|
-
"build:static": "esbuild src/static/__happo__/index.ts --bundle --format=iife --global-name=happoStatic --outfile=tmp/happo-static/bundle.js --platform=browser --target=esnext",
|
|
66
66
|
"build:watch": "tsc --build --watch",
|
|
67
|
-
clean: "rm -rf dist tmp/tsc tmp/happo-
|
|
67
|
+
clean: "rm -rf dist tmp/tsc tmp/happo-custom",
|
|
68
68
|
lint: "eslint .",
|
|
69
69
|
prepublishOnly: "pnpm clean && pnpm build",
|
|
70
70
|
"storybook:dev": "storybook dev --config-dir src/storybook/__tests__/storybook-app -p ${PORT:-6007}",
|
|
71
71
|
test: "node --env-file-if-exists=.env.local ./scripts/test.ts",
|
|
72
|
+
"test:custom": "pnpm build:dist && pnpm build:custom && node --env-file-if-exists=.env.local dist/cli/index.js -c ./happoconfigs/happo.custom.config.ts",
|
|
72
73
|
"test:cypress": "pnpm build:dist && node --env-file-if-exists=.env.local dist/cli/index.js -c ./happoconfigs/happo.cypress.config.ts e2e -- cypress run -C src/cypress/__cypress__/cypress.config.ts",
|
|
73
74
|
"test:cypress:open": "cypress open -C src/cypress/__cypress__/cypress.config.ts",
|
|
74
75
|
"test:playwright": "pnpm build:dist && node --env-file-if-exists=.env.local dist/cli/index.js -c ./happoconfigs/happo.playwright.config.ts e2e -- playwright test",
|
|
75
|
-
"test:static": "pnpm build:dist && pnpm build:static && node --env-file-if-exists=.env.local dist/cli/index.js -c ./happoconfigs/happo.static.config.ts",
|
|
76
76
|
"test:storybook": "pnpm build:dist && node --env-file-if-exists=.env.local dist/cli/index.js -c ./happoconfigs/happo.storybook.config.ts",
|
|
77
|
+
"test:pages": "pnpm build:dist && node --env-file-if-exists=.env.local dist/cli/index.js -c ./happoconfigs/happo.pages.config.ts",
|
|
77
78
|
tsc: "tsc --build tsconfig.json"
|
|
78
79
|
},
|
|
79
80
|
browserslist: {
|
|
@@ -169,4 +170,4 @@ var package_default = {
|
|
|
169
170
|
export {
|
|
170
171
|
package_default
|
|
171
172
|
};
|
|
172
|
-
//# sourceMappingURL=chunk-
|
|
173
|
+
//# sourceMappingURL=chunk-RQIPXFYO.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../package.json"],
|
|
4
|
+
"sourcesContent": ["{\n \"name\": \"happo\",\n \"version\": \"6.0.0-beta.5\",\n \"description\": \"Visual regression testing and accessibility testing\",\n \"license\": \"MIT\",\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+https://github.com/happo/happo.git\"\n },\n \"bugs\": \"https://github.com/happo/happo/issues\",\n \"homepage\": \"https://happo.io\",\n \"bin\": {\n \"happo\": \"dist/cli/index.js\"\n },\n \"type\": \"module\",\n \"main\": \"./dist/config/index.js\",\n \"types\": \"./dist/config/index.d.ts\",\n \"exports\": {\n \".\": {\n \"types\": \"./dist/config/index.d.ts\",\n \"default\": \"./dist/config/index.js\"\n },\n \"./cypress\": {\n \"types\": \"./dist/cypress/index.d.ts\",\n \"default\": \"./dist/cypress/index.js\"\n },\n \"./cypress/task\": {\n \"types\": \"./dist/cypress/task.d.ts\",\n \"default\": \"./dist/cypress/task.js\"\n },\n \"./playwright\": {\n \"types\": \"./dist/playwright/index.d.ts\",\n \"default\": \"./dist/playwright/index.js\"\n },\n \"./custom\": {\n \"types\": \"./dist/custom/index.d.ts\",\n \"default\": \"./dist/custom/index.js\"\n },\n \"./storybook/addon\": {\n \"types\": \"./dist/storybook/browser/addon.d.ts\",\n \"default\": \"./dist/storybook/browser/addon.js\"\n },\n \"./storybook/decorator\": {\n \"types\": \"./dist/storybook/browser/decorator.d.ts\",\n \"default\": \"./dist/storybook/browser/decorator.js\"\n },\n \"./storybook/preset\": {\n \"types\": \"./dist/storybook/preset.d.ts\",\n \"default\": \"./dist/storybook/preset.js\"\n },\n \"./storybook/register\": {\n \"types\": \"./dist/storybook/browser/register.d.ts\",\n \"default\": \"./dist/storybook/browser/register.js\"\n }\n },\n \"files\": [\n \"dist\"\n ],\n \"scripts\": {\n \"all\": \"node ./scripts/allchecks.ts\",\n \"build\": \"pnpm build:types && pnpm build:dist\",\n \"build:custom\": \"esbuild src/custom/__happo__/index.ts --bundle --format=iife --global-name=happoCustom --outfile=tmp/happo-custom/bundle.js --platform=browser --target=esnext\",\n \"build:dist\": \"./scripts/build.ts\",\n \"build:types\": \"pnpm tsc --pretty\",\n \"build:watch\": \"tsc --build --watch\",\n \"clean\": \"rm -rf dist tmp/tsc tmp/happo-custom\",\n \"lint\": \"eslint .\",\n \"prepublishOnly\": \"pnpm clean && pnpm build\",\n \"storybook:dev\": \"storybook dev --config-dir src/storybook/__tests__/storybook-app -p ${PORT:-6007}\",\n \"test\": \"node --env-file-if-exists=.env.local ./scripts/test.ts\",\n \"test:custom\": \"pnpm build:dist && pnpm build:custom && node --env-file-if-exists=.env.local dist/cli/index.js -c ./happoconfigs/happo.custom.config.ts\",\n \"test:cypress\": \"pnpm build:dist && node --env-file-if-exists=.env.local dist/cli/index.js -c ./happoconfigs/happo.cypress.config.ts e2e -- cypress run -C src/cypress/__cypress__/cypress.config.ts\",\n \"test:cypress:open\": \"cypress open -C src/cypress/__cypress__/cypress.config.ts\",\n \"test:playwright\": \"pnpm build:dist && node --env-file-if-exists=.env.local dist/cli/index.js -c ./happoconfigs/happo.playwright.config.ts e2e -- playwright test\",\n \"test:storybook\": \"pnpm build:dist && node --env-file-if-exists=.env.local dist/cli/index.js -c ./happoconfigs/happo.storybook.config.ts\",\n \"test:pages\": \"pnpm build:dist && node --env-file-if-exists=.env.local dist/cli/index.js -c ./happoconfigs/happo.pages.config.ts\",\n \"tsc\": \"tsc --build tsconfig.json\"\n },\n \"browserslist\": {\n \"node\": [\n \"node 22\"\n ],\n \"browser\": [\n \"last 2 Chrome major versions\",\n \"last 2 Firefox major versions\",\n \"last 2 Safari major versions\",\n \"last 2 Edge major versions\"\n ],\n \"isomorphic\": [\n \"node 22\",\n \"last 2 Chrome major versions\",\n \"last 2 Firefox major versions\",\n \"last 2 Safari major versions\",\n \"last 2 Edge major versions\"\n ]\n },\n \"prettier\": {\n \"printWidth\": 85,\n \"singleQuote\": true,\n \"trailingComma\": \"all\",\n \"arrowParens\": \"always\"\n },\n \"devDependencies\": {\n \"@eslint/js\": \"^9.36.0\",\n \"@playwright/test\": \"^1.55.1\",\n \"@reporters/github\": \"^1.11.0\",\n \"@storybook/builder-vite\": \"^10.0.1\",\n \"@storybook/react-vite\": \"^10.0.1\",\n \"@types/adm-zip\": \"^0.5.7\",\n \"@types/archiver\": \"^7.0.0\",\n \"@types/async-retry\": \"^1.4.9\",\n \"@types/base64-stream\": \"^1.0.5\",\n \"@types/jsdom\": \"^27.0.0\",\n \"@types/mime-types\": \"^3.0.1\",\n \"@types/multiparty\": \"^4.2.1\",\n \"@types/node\": \"^24.9.1\",\n \"@types/react\": \"^19.2.0\",\n \"@types/react-dom\": \"^19.2.0\",\n \"@types/serve-handler\": \"^6.1.4\",\n \"adm-zip\": \"^0.5.16\",\n \"cypress\": \"^15.5.0\",\n \"esbuild\": \"^0.25.10\",\n \"eslint\": \"^9.36.0\",\n \"eslint-config-prettier\": \"^10.1.8\",\n \"eslint-plugin-compat\": \"^6.0.2\",\n \"eslint-plugin-depend\": \"^1.3.1\",\n \"eslint-plugin-simple-import-sort\": \"^12.1.1\",\n \"eslint-plugin-unicorn\": \"^62.0.0\",\n \"jiti\": \"^2.6.0\",\n \"jsdom\": \"^27.0.0\",\n \"multiparty\": \"^4.2.3\",\n \"prettier\": \"^3.6.2\",\n \"react\": \"^19.2.0\",\n \"react-dom\": \"^19.2.0\",\n \"react-error-boundary\": \"^6.0.0\",\n \"serve-handler\": \"^6.1.6\",\n \"storybook\": \"^10.0.1\",\n \"typescript\": \"^5.9.2\",\n \"typescript-eslint\": \"^8.44.1\"\n },\n \"dependencies\": {\n \"archiver\": \"^7.0.1\",\n \"async-retry\": \"^1.3.3\",\n \"base64-stream\": \"^1.0.0\",\n \"empathic\": \"^2.0.0\",\n \"image-size\": \"^2.0.2\",\n \"jose\": \"^6.1.0\",\n \"mime-types\": \"^3.0.1\",\n \"p-all\": \"^5.0.1\",\n \"srcset\": \"^5.0.2\",\n \"supports-color\": \"^10.2.2\"\n },\n \"keywords\": [\n \"accessibility\",\n \"cypress\",\n \"playwright\",\n \"regression\",\n \"storybook\",\n \"testing\",\n \"ui\",\n \"visual regression\",\n \"visual\"\n ],\n \"engines\": {\n \"node\": \">=22\"\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
package_default
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-RQIPXFYO.js";
|
|
4
4
|
|
|
5
5
|
// src/network/makeHappoAPIRequest.ts
|
|
6
6
|
import { SignJWT } from "jose";
|
|
@@ -138,4 +138,4 @@ async function makeHappoAPIRequest({ url, path, method = "GET", formData, body }
|
|
|
138
138
|
export {
|
|
139
139
|
makeHappoAPIRequest
|
|
140
140
|
};
|
|
141
|
-
//# sourceMappingURL=chunk-
|
|
141
|
+
//# sourceMappingURL=chunk-RRBBL3EW.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
makeHappoAPIRequest
|
|
3
|
-
} from "./chunk-
|
|
4
|
-
import "./chunk-
|
|
3
|
+
} from "./chunk-RRBBL3EW.js";
|
|
4
|
+
import "./chunk-RQIPXFYO.js";
|
|
5
5
|
|
|
6
6
|
// src/network/createAsyncReport.ts
|
|
7
7
|
function assertResultIsCreateAsyncReportResult(result) {
|
|
@@ -37,4 +37,4 @@ async function createAsyncReport(snapRequestIds, config, { afterSha, link, messa
|
|
|
37
37
|
export {
|
|
38
38
|
createAsyncReport as default
|
|
39
39
|
};
|
|
40
|
-
//# sourceMappingURL=createAsyncReport-
|
|
40
|
+
//# sourceMappingURL=createAsyncReport-IROUZ4HE.js.map
|
package/dist/cli/index.js
CHANGED
|
@@ -31,7 +31,7 @@ async function loadConfigFile(configFilePath) {
|
|
|
31
31
|
if (!config.default.targets) {
|
|
32
32
|
config.default.targets = {
|
|
33
33
|
chrome: {
|
|
34
|
-
|
|
34
|
+
type: "chrome",
|
|
35
35
|
viewport: "1024x768"
|
|
36
36
|
}
|
|
37
37
|
};
|
|
@@ -237,9 +237,7 @@ async function resolveBeforeSha(env, afterSha) {
|
|
|
237
237
|
HAPPO_BASE_BRANCH,
|
|
238
238
|
TRAVIS_COMMIT_RANGE,
|
|
239
239
|
GITHUB_EVENT_PATH,
|
|
240
|
-
SYSTEM_PULLREQUEST_TARGETBRANCH
|
|
241
|
-
// legacy
|
|
242
|
-
BASE_BRANCH
|
|
240
|
+
SYSTEM_PULLREQUEST_TARGETBRANCH
|
|
243
241
|
} = env;
|
|
244
242
|
if (HAPPO_PREVIOUS_SHA) {
|
|
245
243
|
return HAPPO_PREVIOUS_SHA;
|
|
@@ -271,7 +269,7 @@ async function resolveBeforeSha(env, afterSha) {
|
|
|
271
269
|
SYSTEM_PULLREQUEST_TARGETBRANCH.split("/").toReversed()[0]
|
|
272
270
|
].join("/");
|
|
273
271
|
}
|
|
274
|
-
const baseBranch = HAPPO_BASE_BRANCH ||
|
|
272
|
+
const baseBranch = HAPPO_BASE_BRANCH || baseAzureBranch || "origin/main";
|
|
275
273
|
const res = spawnSync("git", ["merge-base", baseBranch, afterSha], {
|
|
276
274
|
encoding: "utf8"
|
|
277
275
|
});
|
|
@@ -293,7 +291,7 @@ function getHeadShaWithLocalChanges() {
|
|
|
293
291
|
if (!headSha) {
|
|
294
292
|
return { headSha: randomSha, headShaWithLocalChanges: randomSha };
|
|
295
293
|
}
|
|
296
|
-
const diffRes = spawnSync("git", ["diff"], {
|
|
294
|
+
const diffRes = spawnSync("git", ["diff", "HEAD"], {
|
|
297
295
|
encoding: "utf8"
|
|
298
296
|
});
|
|
299
297
|
if (diffRes.status !== 0) {
|
|
@@ -411,16 +409,17 @@ async function resolveEnvironment(env = process.env) {
|
|
|
411
409
|
// Resolve message with the SHA that includes local changes
|
|
412
410
|
resolveMessage(env, afterShaWithLocalChanges)
|
|
413
411
|
]);
|
|
412
|
+
const nonNullBeforeSha = beforeSha || afterShaWithLocalChanges;
|
|
414
413
|
const result = {
|
|
415
414
|
link,
|
|
416
415
|
author,
|
|
417
416
|
message,
|
|
418
|
-
beforeSha,
|
|
417
|
+
beforeSha: nonNullBeforeSha,
|
|
419
418
|
afterSha: afterShaWithLocalChanges,
|
|
420
419
|
nonce: env.HAPPO_NONCE,
|
|
421
420
|
debugMode,
|
|
422
421
|
notify: env.HAPPO_NOTIFY,
|
|
423
|
-
fallbackShas: resolveFallbackShas(env,
|
|
422
|
+
fallbackShas: resolveFallbackShas(env, nonNullBeforeSha)
|
|
424
423
|
};
|
|
425
424
|
if (debugMode) {
|
|
426
425
|
console.log("[HAPPO] Raw environment", getRawEnv(env));
|
|
@@ -431,7 +430,7 @@ async function resolveEnvironment(env = process.env) {
|
|
|
431
430
|
|
|
432
431
|
// src/cli/index.ts
|
|
433
432
|
async function getVersion() {
|
|
434
|
-
const packageJson = await import("./package-
|
|
433
|
+
const packageJson = await import("./package-Z7RTWGGQ.js");
|
|
435
434
|
return packageJson.default.version;
|
|
436
435
|
}
|
|
437
436
|
function parseDashdashCommandParts(rawArgs) {
|
|
@@ -531,10 +530,10 @@ async function main(rawArgs = process.argv, logger = console) {
|
|
|
531
530
|
async function handleDefaultCommand(config, environment, logger) {
|
|
532
531
|
logger.log("Running happo tests...");
|
|
533
532
|
const [startJob, createAsyncComparison, createAsyncReport, prepareSnapRequests] = await Promise.all([
|
|
534
|
-
(await import("./startJob-
|
|
535
|
-
(await import("./createAsyncComparison-
|
|
536
|
-
(await import("./createAsyncReport-
|
|
537
|
-
(await import("./prepareSnapRequests-
|
|
533
|
+
(await import("./startJob-5B6M5C6Y.js")).default,
|
|
534
|
+
(await import("./createAsyncComparison-IWILXO74.js")).default,
|
|
535
|
+
(await import("./createAsyncReport-IROUZ4HE.js")).default,
|
|
536
|
+
(await import("./prepareSnapRequests-ULZ2RJ6S.js")).default
|
|
538
537
|
]);
|
|
539
538
|
await startJob(config, environment, logger);
|
|
540
539
|
try {
|
|
@@ -545,12 +544,18 @@ async function handleDefaultCommand(config, environment, logger) {
|
|
|
545
544
|
environment,
|
|
546
545
|
logger
|
|
547
546
|
);
|
|
548
|
-
const asyncComparison = await createAsyncComparison(config, environment, logger);
|
|
549
547
|
logger.log(`[HAPPO] Async report URL: ${asyncReport.url}`);
|
|
550
|
-
|
|
548
|
+
if (environment.beforeSha !== environment.afterSha) {
|
|
549
|
+
const asyncComparison = await createAsyncComparison(
|
|
550
|
+
config,
|
|
551
|
+
environment,
|
|
552
|
+
logger
|
|
553
|
+
);
|
|
554
|
+
logger.log(`[HAPPO] Async comparison URL: ${asyncComparison.compareUrl}`);
|
|
555
|
+
}
|
|
551
556
|
} catch (e) {
|
|
552
557
|
logger.error(e instanceof Error ? e.message : String(e), e);
|
|
553
|
-
const cancelJob = (await import("./cancelJob-
|
|
558
|
+
const cancelJob = (await import("./cancelJob-BTQFKZIA.js")).default;
|
|
554
559
|
await cancelJob("failure", config, environment, logger);
|
|
555
560
|
process.exitCode = 1;
|
|
556
561
|
return;
|
|
@@ -561,7 +566,7 @@ async function handleFinalizeCommand(config, environment, logger) {
|
|
|
561
566
|
logger.log("Config:", config);
|
|
562
567
|
logger.log("Environment:", environment);
|
|
563
568
|
try {
|
|
564
|
-
const finalizeAll = (await import("./wrapper-
|
|
569
|
+
const finalizeAll = (await import("./wrapper-ISNKAWC2.js")).finalizeAll;
|
|
565
570
|
await finalizeAll({ happoConfig: config, environment, logger });
|
|
566
571
|
} catch (e) {
|
|
567
572
|
logger.error(e instanceof Error ? e.message : String(e), e);
|
|
@@ -590,7 +595,7 @@ async function handleE2ECommand(config, environment, dashdashCommandParts, confi
|
|
|
590
595
|
logger.log("Config:", config);
|
|
591
596
|
logger.log("Environment:", environment);
|
|
592
597
|
logger.log("Dashdash command parts:", dashdashCommandParts);
|
|
593
|
-
const runWithWrapper = (await import("./wrapper-
|
|
598
|
+
const runWithWrapper = (await import("./wrapper-ISNKAWC2.js")).default;
|
|
594
599
|
const exitCode = await runWithWrapper(
|
|
595
600
|
dashdashCommandParts,
|
|
596
601
|
config,
|
package/dist/cli/index.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/cli/index.ts", "../../src/config/loadConfig.ts", "../../src/environment/index.ts"],
|
|
4
|
-
"sourcesContent": ["#!/usr/bin/env node\n\nimport path from 'node:path';\nimport { parseArgs } from 'node:util';\n\nimport type { ConfigWithDefaults } from '../config/index.ts';\nimport { findConfigFile, loadConfigFile } from '../config/loadConfig.ts';\nimport type { EnvironmentResult } from '../environment/index.ts';\nimport resolveEnvironment from '../environment/index.ts';\nimport type { Logger } from '../isomorphic/types.ts';\n\nasync function getVersion() {\n const packageJson = await import('../../package.json', {\n with: { type: 'json' },\n });\n return packageJson.default.version;\n}\n\nfunction parseDashdashCommandParts(\n rawArgs: Array<string>,\n): Array<string> | undefined {\n const dashdashIndex = rawArgs.indexOf('--');\n if (dashdashIndex === -1) {\n return undefined;\n }\n return rawArgs.slice(dashdashIndex + 1);\n}\n\nfunction parseRawArgs(rawArgs: Array<string>) {\n const parsedArgs = parseArgs({\n args: rawArgs,\n\n options: {\n version: {\n type: 'boolean',\n short: 'v',\n },\n\n help: {\n type: 'boolean',\n short: 'h',\n },\n\n config: {\n type: 'string',\n short: 'c',\n },\n },\n\n allowPositionals: true,\n });\n\n return {\n ...parsedArgs,\n dashdashCommandParts: parseDashdashCommandParts(rawArgs),\n };\n}\n\nconst helpText = `Happo ${await getVersion()}\nUsage: happo [options]\n\nCommands:\n <default> Run happo tests\n finalize Finalize happo report for Cypress/Playwright tests running in parallel\n\nOptions:\n --config Path to happo config file\n --version Show version number\n --help Show help text\n\nExamples:\n happo\n happo --config path/to/happo.config.ts\n happo --version\n happo --help\n happo -- playwright test\n happo finalize\n `;\n\nfunction makeAbsolute(configFilePath: string): string {\n if (configFilePath.startsWith('.')) {\n return path.resolve(process.cwd(), configFilePath);\n }\n return configFilePath;\n}\n\nexport async function main(\n rawArgs: Array<string> = process.argv,\n logger: Logger = console,\n): Promise<void> {\n const args = parseRawArgs(rawArgs.slice(2));\n // Handle --version flag\n if (args.values.version) {\n logger.log(await getVersion());\n return;\n }\n\n if (args.values.help) {\n logger.log(helpText);\n return;\n }\n\n // Get config file path (use --config if provided, otherwise find default)\n const configFilePath = makeAbsolute(args.values.config || findConfigFile());\n const config = await loadConfigFile(configFilePath);\n const environment = await resolveEnvironment();\n\n // Handle positional arguments (commands)\n const command = args.positionals[0];\n\n if (args.dashdashCommandParts) {\n await handleE2ECommand(\n config,\n environment,\n args.dashdashCommandParts,\n configFilePath,\n logger,\n );\n return;\n }\n\n if (command === 'finalize') {\n await handleFinalizeCommand(config, environment, logger);\n return;\n }\n\n if (command === undefined) {\n await handleDefaultCommand(config, environment, logger);\n return;\n }\n\n logger.error(`Unknown command: ${command}\\n`);\n logger.error(helpText);\n process.exitCode = 1;\n}\n\nasync function handleDefaultCommand(\n config: ConfigWithDefaults,\n environment: EnvironmentResult,\n logger: Logger,\n): Promise<void> {\n logger.log('Running happo tests...');\n\n const [startJob, createAsyncComparison, createAsyncReport, prepareSnapRequests] =\n await Promise.all([\n (await import('../network/startJob.ts')).default,\n (await import('../network/createAsyncComparison.ts')).default,\n (await import('../network/createAsyncReport.ts')).default,\n (await import('../network/prepareSnapRequests.ts')).default,\n ]);\n\n // Tell Happo that we are about to run a job\n await startJob(config, environment, logger);\n\n try {\n // Prepare the snap requests for the job. This includes bundling static\n // assets and uploading them.\n const snapRequestIds = await prepareSnapRequests(config);\n\n // Put together a report from the snap requests.\n const asyncReport = await createAsyncReport(\n snapRequestIds,\n config,\n environment,\n logger,\n );\n\n // Create an async comparison.\n const asyncComparison = await createAsyncComparison(config, environment, logger);\n\n logger.log(`[HAPPO] Async report URL: ${asyncReport.url}`);\n logger.log(`[HAPPO] Async comparison URL: ${asyncComparison.compareUrl}`);\n } catch (e) {\n logger.error(e instanceof Error ? e.message : String(e), e);\n const cancelJob = (await import('../network/cancelJob.ts')).default;\n await cancelJob('failure', config, environment, logger);\n process.exitCode = 1;\n return;\n }\n}\n\nasync function handleFinalizeCommand(\n config: ConfigWithDefaults,\n environment: Awaited<ReturnType<typeof resolveEnvironment>>,\n logger: Logger,\n): Promise<void> {\n logger.log('Finalizing happo report...');\n logger.log('Config:', config);\n logger.log('Environment:', environment);\n\n try {\n const finalizeAll = (await import('../e2e/wrapper.ts')).finalizeAll;\n await finalizeAll({ happoConfig: config, environment, logger });\n } catch (e) {\n logger.error(e instanceof Error ? e.message : String(e), e);\n process.exitCode = 1;\n return;\n }\n process.exitCode = 0;\n return;\n}\n\nconst E2E_INTEGRATION_TYPES = ['cypress', 'playwright'];\n\nasync function handleE2ECommand(\n config: ConfigWithDefaults,\n environment: Awaited<ReturnType<typeof resolveEnvironment>>,\n dashdashCommandParts: Array<string>,\n configFilePath: string,\n logger: Logger,\n): Promise<void> {\n if (!E2E_INTEGRATION_TYPES.includes(config.integration.type)) {\n logger.error(\n `Unsupported integration type used for e2e command: ${config.integration.type}. Supported integration types for e2e are: ${E2E_INTEGRATION_TYPES.join(', ')}`,\n );\n process.exitCode = 1;\n return;\n }\n\n if (!dashdashCommandParts || dashdashCommandParts.length === 0) {\n logger.error('Missing command for e2e action');\n logger.error(helpText);\n process.exitCode = 1;\n return;\n }\n\n logger.log('Setting up happo wrapper for Cypress and Playwright...');\n logger.log('Config:', config);\n logger.log('Environment:', environment);\n logger.log('Dashdash command parts:', dashdashCommandParts);\n\n const runWithWrapper = (await import('../e2e/wrapper.ts')).default;\n const exitCode = await runWithWrapper(\n dashdashCommandParts,\n config,\n environment,\n logger,\n configFilePath,\n );\n process.exitCode = exitCode;\n}\n\nif (import.meta.main) {\n await main();\n}\n", "import { any as findAny } from 'empathic/find';\n\nimport type { ConfigWithDefaults, TargetWithDefaults } from './index.ts';\n\nconst CONFIG_FILENAMES = [\n 'happo.config.js',\n 'happo.config.mjs',\n 'happo.config.cjs',\n 'happo.config.ts',\n 'happo.config.mts',\n 'happo.config.cts',\n];\n\nexport function findConfigFile(): string {\n if (process.env.HAPPO_CONFIG_FILE) {\n return process.env.HAPPO_CONFIG_FILE;\n }\n\n const configFilePath = findAny(CONFIG_FILENAMES, { cwd: process.cwd() });\n\n if (!configFilePath) {\n throw new Error(\n 'Happo config file could not be found. Please create a config file in the root of your project.',\n );\n }\n\n return configFilePath;\n}\n\nexport async function loadConfigFile(\n configFilePath: string,\n): Promise<ConfigWithDefaults> {\n const config = await import(configFilePath);\n if (!config.default.targets) {\n config.default.targets = {\n chrome: {\n browserType: 'chrome',\n viewport: '1024x768',\n },\n };\n }\n if (!config.default.integration) {\n config.default.integration = {\n type: 'storybook',\n };\n }\n const allTargets = Object.values(config.default.targets);\n for (const target of allTargets as Array<TargetWithDefaults>) {\n target.viewport = target.viewport || '1024x768';\n target.freezeAnimations = target.freezeAnimations || 'last-frame';\n }\n return {\n endpoint: 'https://happo.io',\n githubApiUrl: 'https://api.github.com',\n targets: allTargets,\n ...config.default,\n };\n}\n", "import { spawnSync } from 'node:child_process';\nimport crypto, { randomBytes } from 'node:crypto';\nimport { readFileSync } from 'node:fs';\n\ninterface GitHubEvent {\n pull_request?: {\n html_url: string;\n title: string;\n base: {\n sha: string;\n };\n head: {\n sha: string;\n };\n };\n head_commit?: {\n url: string;\n };\n merge_group?: {\n head_sha: string;\n base_sha: string;\n };\n repository?: {\n html_url: string;\n };\n before?: string;\n after?: string;\n}\n\nexport interface EnvironmentResult {\n link: string | undefined;\n message: string | undefined;\n author: string | undefined;\n beforeSha: string | undefined;\n afterSha: string;\n nonce: string | undefined;\n debugMode: boolean;\n notify: string | undefined;\n fallbackShas: Array<string> | undefined;\n}\n\nconst envKeys: ReadonlyArray<string> = [\n 'CIRCLE_PROJECT_REPONAME',\n 'CIRCLE_PROJECT_USERNAME',\n 'CIRCLE_SHA1',\n 'CI_PULL_REQUEST',\n 'GITHUB_BASE',\n 'HAPPO_BASE_BRANCH',\n 'HAPPO_CHANGE_URL',\n 'HAPPO_CURRENT_SHA',\n 'HAPPO_DEBUG',\n 'HAPPO_GITHUB_BASE',\n 'HAPPO_PREVIOUS_SHA',\n 'HAPPO_FALLBACK_SHAS',\n 'HAPPO_FALLBACK_SHAS_COUNT',\n 'TRAVIS_COMMIT',\n 'TRAVIS_PULL_REQUEST',\n 'TRAVIS_PULL_REQUEST_SHA',\n 'TRAVIS_REPO_SLUG',\n 'TRAVIS_COMMIT_RANGE',\n 'BUILD_SOURCEVERSION',\n 'BUILD_REPOSITORY_URI',\n 'SYSTEM_PULLREQUEST_PULLREQUESTID',\n 'SYSTEM_PULLREQUEST_SOURCEBRANCH',\n 'SYSTEM_PULLREQUEST_TARGETBRANCH',\n 'SYSTEM_PULLREQUEST_SOURCEREPOSITORYURI',\n];\n\nasync function resolveGithubEvent(GITHUB_EVENT_PATH: string): Promise<GitHubEvent> {\n try {\n const fs = await import('node:fs/promises');\n const content = await fs.readFile(GITHUB_EVENT_PATH, 'utf8');\n return JSON.parse(content);\n } catch (e) {\n throw new Error(\n `Failed to load GitHub event from the GITHUB_EVENT_PATH environment variable: ${JSON.stringify(GITHUB_EVENT_PATH)}`,\n { cause: e },\n );\n }\n}\n\nasync function resolveLink(\n env: Record<string, string | undefined>,\n): Promise<string | undefined> {\n const {\n HAPPO_CHANGE_URL,\n CI_PULL_REQUEST,\n HAPPO_GITHUB_BASE,\n GITHUB_BASE,\n TRAVIS_REPO_SLUG,\n TRAVIS_PULL_REQUEST,\n TRAVIS_COMMIT,\n CIRCLE_PROJECT_USERNAME,\n CIRCLE_PROJECT_REPONAME,\n CIRCLE_SHA1,\n GITHUB_EVENT_PATH,\n GITHUB_SHA,\n SYSTEM_PULLREQUEST_PULLREQUESTID,\n SYSTEM_PULLREQUEST_SOURCEREPOSITORYURI,\n BUILD_REPOSITORY_URI,\n BUILD_SOURCEVERSION,\n } = env;\n\n if (HAPPO_CHANGE_URL) {\n return HAPPO_CHANGE_URL;\n }\n if (CI_PULL_REQUEST) {\n // Circle CI\n return CI_PULL_REQUEST;\n }\n\n if (GITHUB_EVENT_PATH) {\n const ghEvent = await resolveGithubEvent(GITHUB_EVENT_PATH);\n\n if (ghEvent.pull_request) {\n return ghEvent.pull_request.html_url;\n }\n if (ghEvent.head_commit) {\n return ghEvent.head_commit.url;\n }\n if (ghEvent.merge_group && ghEvent.repository) {\n return `${ghEvent.repository.html_url}/commit/${ghEvent.merge_group.head_sha}`;\n }\n if (GITHUB_SHA && ghEvent.repository) {\n return `${ghEvent.repository.html_url}/commit/${GITHUB_SHA}`;\n }\n }\n\n if (SYSTEM_PULLREQUEST_PULLREQUESTID && SYSTEM_PULLREQUEST_SOURCEREPOSITORYURI) {\n return `${SYSTEM_PULLREQUEST_SOURCEREPOSITORYURI}/pullrequest/${SYSTEM_PULLREQUEST_PULLREQUESTID}`.replace(\n /[^/]+@/,\n '',\n );\n }\n\n if (BUILD_REPOSITORY_URI && BUILD_SOURCEVERSION) {\n return `${BUILD_REPOSITORY_URI}/commit/${BUILD_SOURCEVERSION}`.replace(\n /[^/]+@/,\n '',\n );\n }\n\n const githubBase = HAPPO_GITHUB_BASE || GITHUB_BASE || 'https://github.com';\n\n if (TRAVIS_REPO_SLUG && TRAVIS_PULL_REQUEST) {\n return `${githubBase}/${TRAVIS_REPO_SLUG}/pull/${TRAVIS_PULL_REQUEST}`;\n }\n\n if (TRAVIS_REPO_SLUG && TRAVIS_COMMIT) {\n return `${githubBase}/${TRAVIS_REPO_SLUG}/commit/${TRAVIS_COMMIT}`;\n }\n\n if (CIRCLE_PROJECT_USERNAME && CIRCLE_PROJECT_REPONAME && CIRCLE_SHA1) {\n return `${githubBase}/${CIRCLE_PROJECT_USERNAME}/${CIRCLE_PROJECT_REPONAME}/commit/${CIRCLE_SHA1}`;\n }\n\n return undefined;\n}\n\nasync function resolveAuthorEmail(\n env: Record<string, string | undefined>,\n): Promise<string | undefined> {\n const { GITHUB_EVENT_PATH, HAPPO_AUTHOR } = env;\n\n if (HAPPO_AUTHOR) {\n return HAPPO_AUTHOR;\n }\n\n if (GITHUB_EVENT_PATH) {\n // const ghEvent = await resolveGithubEvent(GITHUB_EVENT_PATH);\n // TODO: do something with the github event\n }\n\n const res = spawnSync('git', ['show', '-s', '--format=%ae'], {\n encoding: 'utf8',\n });\n\n if (res.status !== 0) {\n return undefined;\n }\n\n return res.stdout.trim();\n}\n\nasync function resolveMessage(\n env: Record<string, string | undefined>,\n afterSha: string,\n): Promise<string | undefined> {\n const { GITHUB_EVENT_PATH, HAPPO_MESSAGE } = env;\n\n if (HAPPO_MESSAGE) {\n return HAPPO_MESSAGE;\n }\n if (GITHUB_EVENT_PATH) {\n const ghEvent = await resolveGithubEvent(GITHUB_EVENT_PATH);\n if (ghEvent.pull_request) {\n return ghEvent.pull_request.title;\n }\n }\n\n const res = spawnSync('git', ['log', '-1', '--pretty=%s', afterSha], {\n encoding: 'utf8',\n });\n\n if (res.status !== 0) {\n return undefined;\n }\n\n const message = res.stdout.split('\\n')[0];\n\n if (!message) {\n return undefined;\n }\n\n return message;\n}\n\nfunction resolveShaFromTagMatcher(tagMatcher: string): string | undefined {\n const res = spawnSync(\n 'git',\n ['tag', '--list', tagMatcher, '--sort', 'refname', '--no-contains'],\n {\n encoding: 'utf8',\n },\n );\n if (res.status !== 0) {\n throw new Error(\n `Failed to list git tags when matching against HAPPO_BEFORE_SHA_TAG_MATCHER. Error: ${res.stderr}`,\n );\n }\n const rawAllTags = res.stdout.trim();\n if (!rawAllTags.length) {\n return undefined;\n }\n const allTags = rawAllTags.split('\\n');\n const tag = allTags.at(-1);\n\n if (!tag) {\n throw new Error('No tag found matching the pattern');\n }\n\n const commitRes = spawnSync('git', ['rev-list', '-n', '1', tag], {\n encoding: 'utf8',\n });\n if (commitRes.status !== 0) {\n throw new Error(\n `Failed to resolve commit sha from tag \"${tag}\". Error: ${res.stderr}`,\n );\n }\n return commitRes.stdout.trim();\n}\n\nasync function resolveBeforeSha(\n env: Record<string, string | undefined>,\n afterSha: string,\n): Promise<string | undefined> {\n const {\n HAPPO_PREVIOUS_SHA,\n HAPPO_BEFORE_SHA_TAG_MATCHER,\n HAPPO_BASE_BRANCH,\n TRAVIS_COMMIT_RANGE,\n GITHUB_EVENT_PATH,\n SYSTEM_PULLREQUEST_TARGETBRANCH,\n\n // legacy\n BASE_BRANCH,\n } = env;\n\n if (HAPPO_PREVIOUS_SHA) {\n return HAPPO_PREVIOUS_SHA;\n }\n\n if (HAPPO_BEFORE_SHA_TAG_MATCHER) {\n const resolvedSha = resolveShaFromTagMatcher(HAPPO_BEFORE_SHA_TAG_MATCHER);\n if (resolvedSha) {\n return resolvedSha;\n }\n }\n\n if (GITHUB_EVENT_PATH) {\n const ghEvent = await resolveGithubEvent(GITHUB_EVENT_PATH);\n if (ghEvent.pull_request) {\n return ghEvent.pull_request.base.sha;\n }\n if (ghEvent.merge_group) {\n return ghEvent.merge_group.base_sha;\n }\n return ghEvent.before;\n }\n\n if (TRAVIS_COMMIT_RANGE) {\n const [first] = TRAVIS_COMMIT_RANGE.split('...');\n return first;\n }\n\n let baseAzureBranch;\n if (SYSTEM_PULLREQUEST_TARGETBRANCH) {\n baseAzureBranch = [\n 'origin',\n SYSTEM_PULLREQUEST_TARGETBRANCH.split('/').toReversed()[0],\n ].join('/');\n }\n\n const baseBranch =\n HAPPO_BASE_BRANCH || BASE_BRANCH || baseAzureBranch || 'origin/main';\n const res = spawnSync('git', ['merge-base', baseBranch, afterSha], {\n encoding: 'utf8',\n });\n if (res.status !== 0) {\n console.error(`[HAPPO] Ignored error when resolving base commit: ${res.stderr}`);\n return undefined;\n }\n return res.stdout.split('\\n')[0];\n}\n\nfunction getHeadShaWithLocalChanges(): {\n headSha: string;\n headShaWithLocalChanges: string;\n} {\n const randomSha = randomBytes(20).toString('hex');\n // Get the HEAD sha from the git repo, or if we have local changes, add them to the sha\n const res = spawnSync('git', ['rev-parse', 'HEAD'], {\n encoding: 'utf8',\n });\n if (res.status !== 0) {\n return { headSha: randomSha, headShaWithLocalChanges: randomSha };\n }\n const headSha = res.stdout.split('\\n')[0];\n if (!headSha) {\n return { headSha: randomSha, headShaWithLocalChanges: randomSha };\n }\n\n // Check for local changes\n const diffRes = spawnSync('git', ['diff'], {\n encoding: 'utf8',\n });\n\n // If git diff fails, return HEAD sha\n if (diffRes.status !== 0) {\n return { headSha, headShaWithLocalChanges: headSha };\n }\n\n const lsRes = spawnSync('git', ['ls-files', '--other', '--exclude-standard'], {\n encoding: 'utf8',\n });\n\n if (lsRes.status !== 0) {\n return { headSha, headShaWithLocalChanges: headSha };\n }\n\n const localChanges = [diffRes.stdout.trim(), lsRes.stdout.trim()];\n\n // Get contents of untracked files\n const untrackedFiles = lsRes.stdout\n .trim()\n .split('\\n')\n .filter((file) => file.trim());\n\n for (const file of untrackedFiles) {\n try {\n const content = readFileSync(file, 'utf8');\n localChanges.push(content);\n } catch {\n // If we can't read the file, include just the filename\n localChanges.push(`${file}:<unreadable>`);\n }\n }\n\n const allChanges = localChanges.join('');\n\n if (!allChanges.trim()) {\n return { headSha, headShaWithLocalChanges: headSha };\n }\n\n // If there are local changes, create a hash that includes both HEAD and the changes\n const headShaWithLocalChanges = crypto\n .createHash('sha256')\n .update(headSha)\n .update(allChanges)\n .digest('hex')\n .slice(0, 40);\n\n return { headSha, headShaWithLocalChanges };\n}\n\nasync function resolveAfterSha(\n env: Record<string, string | undefined>,\n): Promise<string | { headSha: string; headShaWithLocalChanges: string }> {\n const {\n HAPPO_CURRENT_SHA,\n CIRCLE_SHA1,\n TRAVIS_PULL_REQUEST_SHA,\n TRAVIS_COMMIT,\n GITHUB_EVENT_PATH,\n GITHUB_SHA,\n BUILD_SOURCEVERSION,\n SYSTEM_PULLREQUEST_SOURCEBRANCH,\n } = env;\n const sha =\n HAPPO_CURRENT_SHA || CIRCLE_SHA1 || TRAVIS_PULL_REQUEST_SHA || TRAVIS_COMMIT;\n if (sha) {\n return sha;\n }\n if (SYSTEM_PULLREQUEST_SOURCEBRANCH) {\n // azure pull request\n const rawBranchName = SYSTEM_PULLREQUEST_SOURCEBRANCH.split('/').toReversed()[0];\n const res = spawnSync('git', ['rev-parse', `origin/${rawBranchName}`], {\n encoding: 'utf8',\n });\n if (res.status === 0 && res.stdout) {\n const sha = res.stdout.split('\\n')[0];\n if (sha) {\n return sha;\n }\n }\n }\n if (BUILD_SOURCEVERSION) {\n // azure master job\n return BUILD_SOURCEVERSION;\n }\n if (GITHUB_EVENT_PATH) {\n const ghEvent = await resolveGithubEvent(GITHUB_EVENT_PATH);\n if (ghEvent.pull_request) {\n return ghEvent.pull_request.head.sha;\n }\n if (ghEvent.merge_group) {\n return ghEvent.merge_group.head_sha;\n }\n if (ghEvent.after) {\n return ghEvent.after;\n }\n if (GITHUB_SHA) {\n return GITHUB_SHA;\n }\n }\n return getHeadShaWithLocalChanges();\n}\n\nfunction resolveFallbackShas(\n env: Record<string, string | undefined>,\n beforeSha: string | undefined,\n): Array<string> | undefined {\n const { HAPPO_FALLBACK_SHAS, HAPPO_FALLBACK_SHAS_COUNT = 50 } = env;\n\n if (HAPPO_FALLBACK_SHAS) {\n return HAPPO_FALLBACK_SHAS.split(/[,\\n]/);\n }\n\n const res = spawnSync(\n 'git',\n [\n 'log',\n '--format=%H',\n '--first-parent',\n `--max-count=${HAPPO_FALLBACK_SHAS_COUNT}`,\n `${beforeSha}^`,\n ],\n {\n encoding: 'utf8',\n },\n );\n if (res.status !== 0) {\n return undefined;\n }\n return res.stdout.split('\\n').filter(Boolean);\n}\n\nfunction getRawEnv(\n env: Record<string, string | undefined>,\n): Record<string, string | undefined> {\n const res: Record<string, string | undefined> = {};\n for (const key of envKeys) {\n res[key] = env[key];\n }\n return res;\n}\n\nexport default async function resolveEnvironment(\n env: Record<string, string | undefined> = process.env,\n): Promise<EnvironmentResult> {\n const debugMode = !!env.HAPPO_DEBUG;\n const afterSha = await resolveAfterSha(env);\n\n const realAfterSha = typeof afterSha === 'string' ? afterSha : afterSha.headSha;\n const afterShaWithLocalChanges =\n typeof afterSha === 'string' ? afterSha : afterSha.headShaWithLocalChanges;\n\n // Resolve the before SHA with the true HEAD SHA\n const [beforeSha, link, author, message] = await Promise.all([\n resolveBeforeSha(env, realAfterSha),\n resolveLink(env),\n resolveAuthorEmail(env),\n\n // Resolve message with the SHA that includes local changes\n resolveMessage(env, afterShaWithLocalChanges),\n ]);\n\n const result = {\n link,\n author,\n message,\n beforeSha,\n afterSha: afterShaWithLocalChanges,\n nonce: env.HAPPO_NONCE,\n debugMode,\n notify: env.HAPPO_NOTIFY,\n fallbackShas: resolveFallbackShas(env, beforeSha),\n };\n\n if (debugMode) {\n console.log('[HAPPO] Raw environment', getRawEnv(env));\n console.log('[HAPPO] Resolved environment', result);\n }\n\n return result;\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["#!/usr/bin/env node\n\nimport path from 'node:path';\nimport { parseArgs } from 'node:util';\n\nimport type { ConfigWithDefaults } from '../config/index.ts';\nimport { findConfigFile, loadConfigFile } from '../config/loadConfig.ts';\nimport type { EnvironmentResult } from '../environment/index.ts';\nimport resolveEnvironment from '../environment/index.ts';\nimport type { Logger } from '../isomorphic/types.ts';\n\nasync function getVersion() {\n const packageJson = await import('../../package.json', {\n with: { type: 'json' },\n });\n return packageJson.default.version;\n}\n\nfunction parseDashdashCommandParts(\n rawArgs: Array<string>,\n): Array<string> | undefined {\n const dashdashIndex = rawArgs.indexOf('--');\n if (dashdashIndex === -1) {\n return undefined;\n }\n return rawArgs.slice(dashdashIndex + 1);\n}\n\nfunction parseRawArgs(rawArgs: Array<string>) {\n const parsedArgs = parseArgs({\n args: rawArgs,\n\n options: {\n version: {\n type: 'boolean',\n short: 'v',\n },\n\n help: {\n type: 'boolean',\n short: 'h',\n },\n\n config: {\n type: 'string',\n short: 'c',\n },\n },\n\n allowPositionals: true,\n });\n\n return {\n ...parsedArgs,\n dashdashCommandParts: parseDashdashCommandParts(rawArgs),\n };\n}\n\nconst helpText = `Happo ${await getVersion()}\nUsage: happo [options]\n\nCommands:\n <default> Run happo tests\n finalize Finalize happo report for Cypress/Playwright tests running in parallel\n\nOptions:\n --config Path to happo config file\n --version Show version number\n --help Show help text\n\nExamples:\n happo\n happo --config path/to/happo.config.ts\n happo --version\n happo --help\n happo -- playwright test\n happo finalize\n `;\n\nfunction makeAbsolute(configFilePath: string): string {\n if (configFilePath.startsWith('.')) {\n return path.resolve(process.cwd(), configFilePath);\n }\n return configFilePath;\n}\n\nexport async function main(\n rawArgs: Array<string> = process.argv,\n logger: Logger = console,\n): Promise<void> {\n const args = parseRawArgs(rawArgs.slice(2));\n // Handle --version flag\n if (args.values.version) {\n logger.log(await getVersion());\n return;\n }\n\n if (args.values.help) {\n logger.log(helpText);\n return;\n }\n\n // Get config file path (use --config if provided, otherwise find default)\n const configFilePath = makeAbsolute(args.values.config || findConfigFile());\n const config = await loadConfigFile(configFilePath);\n const environment = await resolveEnvironment();\n\n // Handle positional arguments (commands)\n const command = args.positionals[0];\n\n if (args.dashdashCommandParts) {\n await handleE2ECommand(\n config,\n environment,\n args.dashdashCommandParts,\n configFilePath,\n logger,\n );\n return;\n }\n\n if (command === 'finalize') {\n await handleFinalizeCommand(config, environment, logger);\n return;\n }\n\n if (command === undefined) {\n await handleDefaultCommand(config, environment, logger);\n return;\n }\n\n logger.error(`Unknown command: ${command}\\n`);\n logger.error(helpText);\n process.exitCode = 1;\n}\n\nasync function handleDefaultCommand(\n config: ConfigWithDefaults,\n environment: EnvironmentResult,\n logger: Logger,\n): Promise<void> {\n logger.log('Running happo tests...');\n\n const [startJob, createAsyncComparison, createAsyncReport, prepareSnapRequests] =\n await Promise.all([\n (await import('../network/startJob.ts')).default,\n (await import('../network/createAsyncComparison.ts')).default,\n (await import('../network/createAsyncReport.ts')).default,\n (await import('../network/prepareSnapRequests.ts')).default,\n ]);\n\n // Tell Happo that we are about to run a job\n await startJob(config, environment, logger);\n\n try {\n // Prepare the snap requests for the job. This includes bundling static\n // assets and uploading them.\n const snapRequestIds = await prepareSnapRequests(config);\n\n // Put together a report from the snap requests.\n const asyncReport = await createAsyncReport(\n snapRequestIds,\n config,\n environment,\n logger,\n );\n\n // Create an async comparison.\n logger.log(`[HAPPO] Async report URL: ${asyncReport.url}`);\n if (environment.beforeSha !== environment.afterSha) {\n const asyncComparison = await createAsyncComparison(\n config,\n environment,\n logger,\n );\n logger.log(`[HAPPO] Async comparison URL: ${asyncComparison.compareUrl}`);\n }\n } catch (e) {\n logger.error(e instanceof Error ? e.message : String(e), e);\n const cancelJob = (await import('../network/cancelJob.ts')).default;\n await cancelJob('failure', config, environment, logger);\n process.exitCode = 1;\n return;\n }\n}\n\nasync function handleFinalizeCommand(\n config: ConfigWithDefaults,\n environment: Awaited<ReturnType<typeof resolveEnvironment>>,\n logger: Logger,\n): Promise<void> {\n logger.log('Finalizing happo report...');\n logger.log('Config:', config);\n logger.log('Environment:', environment);\n\n try {\n const finalizeAll = (await import('../e2e/wrapper.ts')).finalizeAll;\n await finalizeAll({ happoConfig: config, environment, logger });\n } catch (e) {\n logger.error(e instanceof Error ? e.message : String(e), e);\n process.exitCode = 1;\n return;\n }\n process.exitCode = 0;\n return;\n}\n\nconst E2E_INTEGRATION_TYPES = ['cypress', 'playwright'];\n\nasync function handleE2ECommand(\n config: ConfigWithDefaults,\n environment: Awaited<ReturnType<typeof resolveEnvironment>>,\n dashdashCommandParts: Array<string>,\n configFilePath: string,\n logger: Logger,\n): Promise<void> {\n if (!E2E_INTEGRATION_TYPES.includes(config.integration.type)) {\n logger.error(\n `Unsupported integration type used for e2e command: ${config.integration.type}. Supported integration types for e2e are: ${E2E_INTEGRATION_TYPES.join(', ')}`,\n );\n process.exitCode = 1;\n return;\n }\n\n if (!dashdashCommandParts || dashdashCommandParts.length === 0) {\n logger.error('Missing command for e2e action');\n logger.error(helpText);\n process.exitCode = 1;\n return;\n }\n\n logger.log('Setting up happo wrapper for Cypress and Playwright...');\n logger.log('Config:', config);\n logger.log('Environment:', environment);\n logger.log('Dashdash command parts:', dashdashCommandParts);\n\n const runWithWrapper = (await import('../e2e/wrapper.ts')).default;\n const exitCode = await runWithWrapper(\n dashdashCommandParts,\n config,\n environment,\n logger,\n configFilePath,\n );\n process.exitCode = exitCode;\n}\n\nif (import.meta.main) {\n await main();\n}\n", "import { any as findAny } from 'empathic/find';\n\nimport type { ConfigWithDefaults, TargetWithDefaults } from './index.ts';\n\nconst CONFIG_FILENAMES = [\n 'happo.config.js',\n 'happo.config.mjs',\n 'happo.config.cjs',\n 'happo.config.ts',\n 'happo.config.mts',\n 'happo.config.cts',\n];\n\nexport function findConfigFile(): string {\n if (process.env.HAPPO_CONFIG_FILE) {\n return process.env.HAPPO_CONFIG_FILE;\n }\n\n const configFilePath = findAny(CONFIG_FILENAMES, { cwd: process.cwd() });\n\n if (!configFilePath) {\n throw new Error(\n 'Happo config file could not be found. Please create a config file in the root of your project.',\n );\n }\n\n return configFilePath;\n}\n\nexport async function loadConfigFile(\n configFilePath: string,\n): Promise<ConfigWithDefaults> {\n const config = await import(configFilePath);\n if (!config.default.targets) {\n config.default.targets = {\n chrome: {\n type: 'chrome',\n viewport: '1024x768',\n },\n };\n }\n if (!config.default.integration) {\n config.default.integration = {\n type: 'storybook',\n };\n }\n const allTargets = Object.values(config.default.targets);\n for (const target of allTargets as Array<TargetWithDefaults>) {\n target.viewport = target.viewport || '1024x768';\n target.freezeAnimations = target.freezeAnimations || 'last-frame';\n }\n return {\n endpoint: 'https://happo.io',\n githubApiUrl: 'https://api.github.com',\n targets: allTargets,\n ...config.default,\n };\n}\n", "import { spawnSync } from 'node:child_process';\nimport crypto, { randomBytes } from 'node:crypto';\nimport { readFileSync } from 'node:fs';\n\ninterface GitHubEvent {\n pull_request?: {\n html_url: string;\n title: string;\n base: {\n sha: string;\n };\n head: {\n sha: string;\n };\n };\n head_commit?: {\n url: string;\n };\n merge_group?: {\n head_sha: string;\n base_sha: string;\n };\n repository?: {\n html_url: string;\n };\n before?: string;\n after?: string;\n}\n\nexport interface EnvironmentResult {\n link: string | undefined;\n message: string | undefined;\n author: string | undefined;\n beforeSha: string;\n afterSha: string;\n nonce: string | undefined;\n debugMode: boolean;\n notify: string | undefined;\n fallbackShas: Array<string> | undefined;\n}\n\nconst envKeys: ReadonlyArray<string> = [\n 'CIRCLE_PROJECT_REPONAME',\n 'CIRCLE_PROJECT_USERNAME',\n 'CIRCLE_SHA1',\n 'CI_PULL_REQUEST',\n 'GITHUB_BASE',\n 'HAPPO_BASE_BRANCH',\n 'HAPPO_CHANGE_URL',\n 'HAPPO_CURRENT_SHA',\n 'HAPPO_DEBUG',\n 'HAPPO_GITHUB_BASE',\n 'HAPPO_PREVIOUS_SHA',\n 'HAPPO_FALLBACK_SHAS',\n 'HAPPO_FALLBACK_SHAS_COUNT',\n 'TRAVIS_COMMIT',\n 'TRAVIS_PULL_REQUEST',\n 'TRAVIS_PULL_REQUEST_SHA',\n 'TRAVIS_REPO_SLUG',\n 'TRAVIS_COMMIT_RANGE',\n 'BUILD_SOURCEVERSION',\n 'BUILD_REPOSITORY_URI',\n 'SYSTEM_PULLREQUEST_PULLREQUESTID',\n 'SYSTEM_PULLREQUEST_SOURCEBRANCH',\n 'SYSTEM_PULLREQUEST_TARGETBRANCH',\n 'SYSTEM_PULLREQUEST_SOURCEREPOSITORYURI',\n];\n\nasync function resolveGithubEvent(GITHUB_EVENT_PATH: string): Promise<GitHubEvent> {\n try {\n const fs = await import('node:fs/promises');\n const content = await fs.readFile(GITHUB_EVENT_PATH, 'utf8');\n return JSON.parse(content);\n } catch (e) {\n throw new Error(\n `Failed to load GitHub event from the GITHUB_EVENT_PATH environment variable: ${JSON.stringify(GITHUB_EVENT_PATH)}`,\n { cause: e },\n );\n }\n}\n\nasync function resolveLink(\n env: Record<string, string | undefined>,\n): Promise<string | undefined> {\n const {\n HAPPO_CHANGE_URL,\n CI_PULL_REQUEST,\n HAPPO_GITHUB_BASE,\n GITHUB_BASE,\n TRAVIS_REPO_SLUG,\n TRAVIS_PULL_REQUEST,\n TRAVIS_COMMIT,\n CIRCLE_PROJECT_USERNAME,\n CIRCLE_PROJECT_REPONAME,\n CIRCLE_SHA1,\n GITHUB_EVENT_PATH,\n GITHUB_SHA,\n SYSTEM_PULLREQUEST_PULLREQUESTID,\n SYSTEM_PULLREQUEST_SOURCEREPOSITORYURI,\n BUILD_REPOSITORY_URI,\n BUILD_SOURCEVERSION,\n } = env;\n\n if (HAPPO_CHANGE_URL) {\n return HAPPO_CHANGE_URL;\n }\n if (CI_PULL_REQUEST) {\n // Circle CI\n return CI_PULL_REQUEST;\n }\n\n if (GITHUB_EVENT_PATH) {\n const ghEvent = await resolveGithubEvent(GITHUB_EVENT_PATH);\n\n if (ghEvent.pull_request) {\n return ghEvent.pull_request.html_url;\n }\n if (ghEvent.head_commit) {\n return ghEvent.head_commit.url;\n }\n if (ghEvent.merge_group && ghEvent.repository) {\n return `${ghEvent.repository.html_url}/commit/${ghEvent.merge_group.head_sha}`;\n }\n if (GITHUB_SHA && ghEvent.repository) {\n return `${ghEvent.repository.html_url}/commit/${GITHUB_SHA}`;\n }\n }\n\n if (SYSTEM_PULLREQUEST_PULLREQUESTID && SYSTEM_PULLREQUEST_SOURCEREPOSITORYURI) {\n return `${SYSTEM_PULLREQUEST_SOURCEREPOSITORYURI}/pullrequest/${SYSTEM_PULLREQUEST_PULLREQUESTID}`.replace(\n /[^/]+@/,\n '',\n );\n }\n\n if (BUILD_REPOSITORY_URI && BUILD_SOURCEVERSION) {\n return `${BUILD_REPOSITORY_URI}/commit/${BUILD_SOURCEVERSION}`.replace(\n /[^/]+@/,\n '',\n );\n }\n\n const githubBase = HAPPO_GITHUB_BASE || GITHUB_BASE || 'https://github.com';\n\n if (TRAVIS_REPO_SLUG && TRAVIS_PULL_REQUEST) {\n return `${githubBase}/${TRAVIS_REPO_SLUG}/pull/${TRAVIS_PULL_REQUEST}`;\n }\n\n if (TRAVIS_REPO_SLUG && TRAVIS_COMMIT) {\n return `${githubBase}/${TRAVIS_REPO_SLUG}/commit/${TRAVIS_COMMIT}`;\n }\n\n if (CIRCLE_PROJECT_USERNAME && CIRCLE_PROJECT_REPONAME && CIRCLE_SHA1) {\n return `${githubBase}/${CIRCLE_PROJECT_USERNAME}/${CIRCLE_PROJECT_REPONAME}/commit/${CIRCLE_SHA1}`;\n }\n\n return undefined;\n}\n\nasync function resolveAuthorEmail(\n env: Record<string, string | undefined>,\n): Promise<string | undefined> {\n const { GITHUB_EVENT_PATH, HAPPO_AUTHOR } = env;\n\n if (HAPPO_AUTHOR) {\n return HAPPO_AUTHOR;\n }\n\n if (GITHUB_EVENT_PATH) {\n // const ghEvent = await resolveGithubEvent(GITHUB_EVENT_PATH);\n // TODO: do something with the github event\n }\n\n const res = spawnSync('git', ['show', '-s', '--format=%ae'], {\n encoding: 'utf8',\n });\n\n if (res.status !== 0) {\n return undefined;\n }\n\n return res.stdout.trim();\n}\n\nasync function resolveMessage(\n env: Record<string, string | undefined>,\n afterSha: string,\n): Promise<string | undefined> {\n const { GITHUB_EVENT_PATH, HAPPO_MESSAGE } = env;\n\n if (HAPPO_MESSAGE) {\n return HAPPO_MESSAGE;\n }\n if (GITHUB_EVENT_PATH) {\n const ghEvent = await resolveGithubEvent(GITHUB_EVENT_PATH);\n if (ghEvent.pull_request) {\n return ghEvent.pull_request.title;\n }\n }\n\n const res = spawnSync('git', ['log', '-1', '--pretty=%s', afterSha], {\n encoding: 'utf8',\n });\n\n if (res.status !== 0) {\n return undefined;\n }\n\n const message = res.stdout.split('\\n')[0];\n\n if (!message) {\n return undefined;\n }\n\n return message;\n}\n\nfunction resolveShaFromTagMatcher(tagMatcher: string): string | undefined {\n const res = spawnSync(\n 'git',\n ['tag', '--list', tagMatcher, '--sort', 'refname', '--no-contains'],\n {\n encoding: 'utf8',\n },\n );\n if (res.status !== 0) {\n throw new Error(\n `Failed to list git tags when matching against HAPPO_BEFORE_SHA_TAG_MATCHER. Error: ${res.stderr}`,\n );\n }\n const rawAllTags = res.stdout.trim();\n if (!rawAllTags.length) {\n return undefined;\n }\n const allTags = rawAllTags.split('\\n');\n const tag = allTags.at(-1);\n\n if (!tag) {\n throw new Error('No tag found matching the pattern');\n }\n\n const commitRes = spawnSync('git', ['rev-list', '-n', '1', tag], {\n encoding: 'utf8',\n });\n if (commitRes.status !== 0) {\n throw new Error(\n `Failed to resolve commit sha from tag \"${tag}\". Error: ${res.stderr}`,\n );\n }\n return commitRes.stdout.trim();\n}\n\nasync function resolveBeforeSha(\n env: Record<string, string | undefined>,\n afterSha: string,\n): Promise<string | undefined> {\n const {\n HAPPO_PREVIOUS_SHA,\n HAPPO_BEFORE_SHA_TAG_MATCHER,\n HAPPO_BASE_BRANCH,\n TRAVIS_COMMIT_RANGE,\n GITHUB_EVENT_PATH,\n SYSTEM_PULLREQUEST_TARGETBRANCH,\n } = env;\n\n if (HAPPO_PREVIOUS_SHA) {\n return HAPPO_PREVIOUS_SHA;\n }\n\n if (HAPPO_BEFORE_SHA_TAG_MATCHER) {\n const resolvedSha = resolveShaFromTagMatcher(HAPPO_BEFORE_SHA_TAG_MATCHER);\n if (resolvedSha) {\n return resolvedSha;\n }\n }\n\n if (GITHUB_EVENT_PATH) {\n const ghEvent = await resolveGithubEvent(GITHUB_EVENT_PATH);\n if (ghEvent.pull_request) {\n return ghEvent.pull_request.base.sha;\n }\n if (ghEvent.merge_group) {\n return ghEvent.merge_group.base_sha;\n }\n return ghEvent.before;\n }\n\n if (TRAVIS_COMMIT_RANGE) {\n const [first] = TRAVIS_COMMIT_RANGE.split('...');\n return first;\n }\n\n let baseAzureBranch;\n if (SYSTEM_PULLREQUEST_TARGETBRANCH) {\n baseAzureBranch = [\n 'origin',\n SYSTEM_PULLREQUEST_TARGETBRANCH.split('/').toReversed()[0],\n ].join('/');\n }\n\n const baseBranch = HAPPO_BASE_BRANCH || baseAzureBranch || 'origin/main';\n const res = spawnSync('git', ['merge-base', baseBranch, afterSha], {\n encoding: 'utf8',\n });\n if (res.status !== 0) {\n console.error(`[HAPPO] Ignored error when resolving base commit: ${res.stderr}`);\n return undefined;\n }\n return res.stdout.split('\\n')[0];\n}\n\nfunction getHeadShaWithLocalChanges(): {\n headSha: string;\n headShaWithLocalChanges: string;\n} {\n const randomSha = randomBytes(20).toString('hex');\n // Get the HEAD sha from the git repo, or if we have local changes, add them to the sha\n const res = spawnSync('git', ['rev-parse', 'HEAD'], {\n encoding: 'utf8',\n });\n if (res.status !== 0) {\n return { headSha: randomSha, headShaWithLocalChanges: randomSha };\n }\n const headSha = res.stdout.split('\\n')[0];\n if (!headSha) {\n return { headSha: randomSha, headShaWithLocalChanges: randomSha };\n }\n\n // Check for local changes\n const diffRes = spawnSync('git', ['diff', 'HEAD'], {\n encoding: 'utf8',\n });\n\n // If git diff fails, return HEAD sha\n if (diffRes.status !== 0) {\n return { headSha, headShaWithLocalChanges: headSha };\n }\n\n const lsRes = spawnSync('git', ['ls-files', '--other', '--exclude-standard'], {\n encoding: 'utf8',\n });\n\n if (lsRes.status !== 0) {\n return { headSha, headShaWithLocalChanges: headSha };\n }\n\n const localChanges = [diffRes.stdout.trim(), lsRes.stdout.trim()];\n\n // Get contents of untracked files\n const untrackedFiles = lsRes.stdout\n .trim()\n .split('\\n')\n .filter((file) => file.trim());\n\n for (const file of untrackedFiles) {\n try {\n const content = readFileSync(file, 'utf8');\n localChanges.push(content);\n } catch {\n // If we can't read the file, include just the filename\n localChanges.push(`${file}:<unreadable>`);\n }\n }\n\n const allChanges = localChanges.join('');\n\n if (!allChanges.trim()) {\n return { headSha, headShaWithLocalChanges: headSha };\n }\n\n // If there are local changes, create a hash that includes both HEAD and the changes\n const headShaWithLocalChanges = crypto\n .createHash('sha256')\n .update(headSha)\n .update(allChanges)\n .digest('hex')\n .slice(0, 40);\n\n return { headSha, headShaWithLocalChanges };\n}\n\nasync function resolveAfterSha(\n env: Record<string, string | undefined>,\n): Promise<string | { headSha: string; headShaWithLocalChanges: string }> {\n const {\n HAPPO_CURRENT_SHA,\n CIRCLE_SHA1,\n TRAVIS_PULL_REQUEST_SHA,\n TRAVIS_COMMIT,\n GITHUB_EVENT_PATH,\n GITHUB_SHA,\n BUILD_SOURCEVERSION,\n SYSTEM_PULLREQUEST_SOURCEBRANCH,\n } = env;\n const sha =\n HAPPO_CURRENT_SHA || CIRCLE_SHA1 || TRAVIS_PULL_REQUEST_SHA || TRAVIS_COMMIT;\n if (sha) {\n return sha;\n }\n if (SYSTEM_PULLREQUEST_SOURCEBRANCH) {\n // azure pull request\n const rawBranchName = SYSTEM_PULLREQUEST_SOURCEBRANCH.split('/').toReversed()[0];\n const res = spawnSync('git', ['rev-parse', `origin/${rawBranchName}`], {\n encoding: 'utf8',\n });\n if (res.status === 0 && res.stdout) {\n const sha = res.stdout.split('\\n')[0];\n if (sha) {\n return sha;\n }\n }\n }\n if (BUILD_SOURCEVERSION) {\n // azure master job\n return BUILD_SOURCEVERSION;\n }\n if (GITHUB_EVENT_PATH) {\n const ghEvent = await resolveGithubEvent(GITHUB_EVENT_PATH);\n if (ghEvent.pull_request) {\n return ghEvent.pull_request.head.sha;\n }\n if (ghEvent.merge_group) {\n return ghEvent.merge_group.head_sha;\n }\n if (ghEvent.after) {\n return ghEvent.after;\n }\n if (GITHUB_SHA) {\n return GITHUB_SHA;\n }\n }\n return getHeadShaWithLocalChanges();\n}\n\nfunction resolveFallbackShas(\n env: Record<string, string | undefined>,\n beforeSha: string | undefined,\n): Array<string> | undefined {\n const { HAPPO_FALLBACK_SHAS, HAPPO_FALLBACK_SHAS_COUNT = 50 } = env;\n\n if (HAPPO_FALLBACK_SHAS) {\n return HAPPO_FALLBACK_SHAS.split(/[,\\n]/);\n }\n\n const res = spawnSync(\n 'git',\n [\n 'log',\n '--format=%H',\n '--first-parent',\n `--max-count=${HAPPO_FALLBACK_SHAS_COUNT}`,\n `${beforeSha}^`,\n ],\n {\n encoding: 'utf8',\n },\n );\n if (res.status !== 0) {\n return undefined;\n }\n return res.stdout.split('\\n').filter(Boolean);\n}\n\nfunction getRawEnv(\n env: Record<string, string | undefined>,\n): Record<string, string | undefined> {\n const res: Record<string, string | undefined> = {};\n for (const key of envKeys) {\n res[key] = env[key];\n }\n return res;\n}\n\nexport default async function resolveEnvironment(\n env: Record<string, string | undefined> = process.env,\n): Promise<EnvironmentResult> {\n const debugMode = !!env.HAPPO_DEBUG;\n const afterSha = await resolveAfterSha(env);\n\n const realAfterSha = typeof afterSha === 'string' ? afterSha : afterSha.headSha;\n const afterShaWithLocalChanges =\n typeof afterSha === 'string' ? afterSha : afterSha.headShaWithLocalChanges;\n\n // Resolve the before SHA with the true HEAD SHA\n const [beforeSha, link, author, message] = await Promise.all([\n resolveBeforeSha(env, realAfterSha),\n resolveLink(env),\n resolveAuthorEmail(env),\n\n // Resolve message with the SHA that includes local changes\n resolveMessage(env, afterShaWithLocalChanges),\n ]);\n\n const nonNullBeforeSha = beforeSha || afterShaWithLocalChanges;\n\n const result = {\n link,\n author,\n message,\n beforeSha: nonNullBeforeSha,\n afterSha: afterShaWithLocalChanges,\n nonce: env.HAPPO_NONCE,\n debugMode,\n notify: env.HAPPO_NOTIFY,\n fallbackShas: resolveFallbackShas(env, nonNullBeforeSha),\n };\n\n if (debugMode) {\n console.log('[HAPPO] Raw environment', getRawEnv(env));\n console.log('[HAPPO] Resolved environment', result);\n }\n\n return result;\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["sha"]
|
|
7
7
|
}
|