happo 6.0.0-beta.2 → 6.0.0-beta.4
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 +7 -14
- package/dist/cli/{cancelJob-VEJGYUSM.js → cancelJob-CUQGXFMH.js} +3 -3
- package/dist/cli/{chunk-IS4ZMP6S.js → chunk-3MTOMTXF.js} +2 -3
- package/dist/cli/{chunk-JUNBOLIK.js → chunk-DEPMYALB.js} +8 -8
- package/dist/cli/chunk-DEPMYALB.js.map +7 -0
- package/dist/cli/{createAsyncComparison-2GKE5XXV.js → chunk-NYAYX7MB.js} +9 -4
- package/dist/cli/chunk-NYAYX7MB.js.map +7 -0
- package/dist/cli/createAsyncComparison-SHJLERF3.js +9 -0
- package/dist/cli/{createAsyncReport-O32MDG4M.js → createAsyncReport-K5NVGHN4.js} +3 -3
- package/dist/cli/index.js +19 -12
- package/dist/cli/index.js.map +2 -2
- package/dist/cli/package-B6XCYNDY.js +7 -0
- package/dist/cli/package-B6XCYNDY.js.map +7 -0
- package/dist/cli/{prepareSnapRequests-WXQMSHSS.js → prepareSnapRequests-6AAMGIDH.js} +60 -79
- package/dist/cli/prepareSnapRequests-6AAMGIDH.js.map +7 -0
- package/dist/cli/{startJob-KCYLIUR3.js → startJob-3QDFFZMR.js} +3 -3
- package/dist/cli/{wrapper-QX2FX5O4.js → wrapper-4JGH37FT.js} +44 -82
- package/dist/cli/wrapper-4JGH37FT.js.map +7 -0
- package/dist/config/RemoteBrowserTarget.d.ts +4 -2
- package/dist/config/RemoteBrowserTarget.d.ts.map +1 -1
- package/dist/config/index.d.ts +14 -9
- 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 +12 -73
- package/dist/cypress/task.js.map +2 -2
- 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/network/uploadAssets.d.ts.map +1 -1
- package/dist/playwright/index.js +12 -73
- 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 +7 -7
- package/dist/cli/chunk-JUNBOLIK.js.map +0 -7
- package/dist/cli/createAsyncComparison-2GKE5XXV.js.map +0 -7
- package/dist/cli/package-RYVZDHU4.js +0 -7
- package/dist/cli/prepareSnapRequests-WXQMSHSS.js.map +0 -7
- package/dist/cli/wrapper-QX2FX5O4.js.map +0 -7
- /package/dist/cli/{cancelJob-VEJGYUSM.js.map → cancelJob-CUQGXFMH.js.map} +0 -0
- /package/dist/cli/{chunk-IS4ZMP6S.js.map → chunk-3MTOMTXF.js.map} +0 -0
- /package/dist/cli/{package-RYVZDHU4.js.map → createAsyncComparison-SHJLERF3.js.map} +0 -0
- /package/dist/cli/{createAsyncReport-O32MDG4M.js.map → createAsyncReport-K5NVGHN4.js.map} +0 -0
- /package/dist/cli/{startJob-KCYLIUR3.js.map → startJob-3QDFFZMR.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
|
|
|
@@ -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-3MTOMTXF.js";
|
|
4
|
+
import "./chunk-DEPMYALB.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-CUQGXFMH.js.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
package_default
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-DEPMYALB.js";
|
|
4
4
|
|
|
5
5
|
// src/network/makeHappoAPIRequest.ts
|
|
6
6
|
import { SignJWT } from "jose";
|
|
@@ -136,7 +136,6 @@ async function makeHappoAPIRequest({ url, path, method = "GET", formData, body }
|
|
|
136
136
|
}
|
|
137
137
|
|
|
138
138
|
export {
|
|
139
|
-
ErrorWithStatusCode,
|
|
140
139
|
makeHappoAPIRequest
|
|
141
140
|
};
|
|
142
|
-
//# sourceMappingURL=chunk-
|
|
141
|
+
//# sourceMappingURL=chunk-3MTOMTXF.js.map
|
|
@@ -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.4",
|
|
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,19 +60,19 @@ 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 && cp src/static/__happo__/iframe.html tmp/happo-static/",
|
|
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
77
|
tsc: "tsc --build tsconfig.json"
|
|
78
78
|
},
|
|
@@ -169,4 +169,4 @@ var package_default = {
|
|
|
169
169
|
export {
|
|
170
170
|
package_default
|
|
171
171
|
};
|
|
172
|
-
//# sourceMappingURL=chunk-
|
|
172
|
+
//# sourceMappingURL=chunk-DEPMYALB.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.4\",\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 \"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,7 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
makeHappoAPIRequest
|
|
3
|
-
} from "./chunk-
|
|
4
|
-
import "./chunk-JUNBOLIK.js";
|
|
3
|
+
} from "./chunk-3MTOMTXF.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-NYAYX7MB.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
|
import {
|
|
2
2
|
makeHappoAPIRequest
|
|
3
|
-
} from "./chunk-
|
|
4
|
-
import "./chunk-
|
|
3
|
+
} from "./chunk-3MTOMTXF.js";
|
|
4
|
+
import "./chunk-DEPMYALB.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-K5NVGHN4.js.map
|
package/dist/cli/index.js
CHANGED
|
@@ -411,16 +411,17 @@ async function resolveEnvironment(env = process.env) {
|
|
|
411
411
|
// Resolve message with the SHA that includes local changes
|
|
412
412
|
resolveMessage(env, afterShaWithLocalChanges)
|
|
413
413
|
]);
|
|
414
|
+
const nonNullBeforeSha = beforeSha || afterShaWithLocalChanges;
|
|
414
415
|
const result = {
|
|
415
416
|
link,
|
|
416
417
|
author,
|
|
417
418
|
message,
|
|
418
|
-
beforeSha,
|
|
419
|
+
beforeSha: nonNullBeforeSha,
|
|
419
420
|
afterSha: afterShaWithLocalChanges,
|
|
420
421
|
nonce: env.HAPPO_NONCE,
|
|
421
422
|
debugMode,
|
|
422
423
|
notify: env.HAPPO_NOTIFY,
|
|
423
|
-
fallbackShas: resolveFallbackShas(env,
|
|
424
|
+
fallbackShas: resolveFallbackShas(env, nonNullBeforeSha)
|
|
424
425
|
};
|
|
425
426
|
if (debugMode) {
|
|
426
427
|
console.log("[HAPPO] Raw environment", getRawEnv(env));
|
|
@@ -431,7 +432,7 @@ async function resolveEnvironment(env = process.env) {
|
|
|
431
432
|
|
|
432
433
|
// src/cli/index.ts
|
|
433
434
|
async function getVersion() {
|
|
434
|
-
const packageJson = await import("./package-
|
|
435
|
+
const packageJson = await import("./package-B6XCYNDY.js");
|
|
435
436
|
return packageJson.default.version;
|
|
436
437
|
}
|
|
437
438
|
function parseDashdashCommandParts(rawArgs) {
|
|
@@ -531,10 +532,10 @@ async function main(rawArgs = process.argv, logger = console) {
|
|
|
531
532
|
async function handleDefaultCommand(config, environment, logger) {
|
|
532
533
|
logger.log("Running happo tests...");
|
|
533
534
|
const [startJob, createAsyncComparison, createAsyncReport, prepareSnapRequests] = await Promise.all([
|
|
534
|
-
(await import("./startJob-
|
|
535
|
-
(await import("./createAsyncComparison-
|
|
536
|
-
(await import("./createAsyncReport-
|
|
537
|
-
(await import("./prepareSnapRequests-
|
|
535
|
+
(await import("./startJob-3QDFFZMR.js")).default,
|
|
536
|
+
(await import("./createAsyncComparison-SHJLERF3.js")).default,
|
|
537
|
+
(await import("./createAsyncReport-K5NVGHN4.js")).default,
|
|
538
|
+
(await import("./prepareSnapRequests-6AAMGIDH.js")).default
|
|
538
539
|
]);
|
|
539
540
|
await startJob(config, environment, logger);
|
|
540
541
|
try {
|
|
@@ -545,12 +546,18 @@ async function handleDefaultCommand(config, environment, logger) {
|
|
|
545
546
|
environment,
|
|
546
547
|
logger
|
|
547
548
|
);
|
|
548
|
-
const asyncComparison = await createAsyncComparison(config, environment, logger);
|
|
549
549
|
logger.log(`[HAPPO] Async report URL: ${asyncReport.url}`);
|
|
550
|
-
|
|
550
|
+
if (environment.beforeSha !== environment.afterSha) {
|
|
551
|
+
const asyncComparison = await createAsyncComparison(
|
|
552
|
+
config,
|
|
553
|
+
environment,
|
|
554
|
+
logger
|
|
555
|
+
);
|
|
556
|
+
logger.log(`[HAPPO] Async comparison URL: ${asyncComparison.compareUrl}`);
|
|
557
|
+
}
|
|
551
558
|
} catch (e) {
|
|
552
559
|
logger.error(e instanceof Error ? e.message : String(e), e);
|
|
553
|
-
const cancelJob = (await import("./cancelJob-
|
|
560
|
+
const cancelJob = (await import("./cancelJob-CUQGXFMH.js")).default;
|
|
554
561
|
await cancelJob("failure", config, environment, logger);
|
|
555
562
|
process.exitCode = 1;
|
|
556
563
|
return;
|
|
@@ -561,7 +568,7 @@ async function handleFinalizeCommand(config, environment, logger) {
|
|
|
561
568
|
logger.log("Config:", config);
|
|
562
569
|
logger.log("Environment:", environment);
|
|
563
570
|
try {
|
|
564
|
-
const finalizeAll = (await import("./wrapper-
|
|
571
|
+
const finalizeAll = (await import("./wrapper-4JGH37FT.js")).finalizeAll;
|
|
565
572
|
await finalizeAll({ happoConfig: config, environment, logger });
|
|
566
573
|
} catch (e) {
|
|
567
574
|
logger.error(e instanceof Error ? e.message : String(e), e);
|
|
@@ -590,7 +597,7 @@ async function handleE2ECommand(config, environment, dashdashCommandParts, confi
|
|
|
590
597
|
logger.log("Config:", config);
|
|
591
598
|
logger.log("Environment:", environment);
|
|
592
599
|
logger.log("Dashdash command parts:", dashdashCommandParts);
|
|
593
|
-
const runWithWrapper = (await import("./wrapper-
|
|
600
|
+
const runWithWrapper = (await import("./wrapper-4JGH37FT.js")).default;
|
|
594
601
|
const exitCode = await runWithWrapper(
|
|
595
602
|
dashdashCommandParts,
|
|
596
603
|
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 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;\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 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
|
}
|