@reshotdev/screenshot 0.0.1-beta.11 → 0.0.1-beta.12

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.
@@ -16,7 +16,7 @@
16
16
  document.documentElement.style.colorScheme = isDark ? 'dark' : 'light';
17
17
  })();
18
18
  </script>
19
- <script type="module" crossorigin src="/assets/index-D2qqcFNN.js"></script>
19
+ <script type="module" crossorigin src="/assets/index-CvleJUur.js"></script>
20
20
  <link rel="stylesheet" crossorigin href="/assets/index-n468W0Wr.css">
21
21
  </head>
22
22
  <body>
@@ -1,178 +0,0 @@
1
- // ci-run.js - Composite command: run + publish in one step (CI-optimized)
2
- const chalk = require("chalk");
3
- const fs = require("fs-extra");
4
- const path = require("path");
5
- const { detectCI, getCIMetadata } = require("../lib/ci-detect");
6
-
7
- async function ciRunCommand(options = {}) {
8
- const {
9
- config: configPath,
10
- tag,
11
- message,
12
- dryRun,
13
- publish: shouldPublish = true,
14
- skipReleaseDoctor = false,
15
- } = options;
16
-
17
- // Disable colors in CI for cleaner logs
18
- const { isCI, provider } = detectCI();
19
- if (isCI) {
20
- process.env.NO_COLOR = "1";
21
- }
22
-
23
- const ciMeta = getCIMetadata();
24
-
25
- console.log(chalk.cyan("šŸ¤– Reshot CI Run\n"));
26
- if (isCI) {
27
- console.log(chalk.gray(` Provider: ${provider || "unknown"}`));
28
- if (ciMeta.commitSha) {
29
- console.log(chalk.gray(` Commit: ${ciMeta.commitSha.slice(0, 8)}`));
30
- }
31
- if (ciMeta.branch) {
32
- console.log(chalk.gray(` Branch: ${ciMeta.branch}`));
33
- }
34
- console.log();
35
- }
36
-
37
- // Override config path if specified
38
- if (configPath) {
39
- process.env.RESHOT_CONFIG_PATH = configPath;
40
- }
41
-
42
- const ciResult = {
43
- releaseDoctor: null,
44
- run: { success: false, scenariosRun: 0, scenariosFailed: 0 },
45
- publish: null,
46
- ci: ciMeta,
47
- timestamp: new Date().toISOString(),
48
- };
49
-
50
- if (!skipReleaseDoctor) {
51
- console.log(chalk.cyan("━━━ Step 0: Release Doctor ━━━\n"));
52
- try {
53
- const { runReleaseDoctor } = require("../lib/release-doctor");
54
- const releaseDoctor = await runReleaseDoctor({});
55
- ciResult.releaseDoctor = {
56
- success: releaseDoctor.ok,
57
- reportPath: releaseDoctor.reportPath || null,
58
- };
59
-
60
- if (!releaseDoctor.ok) {
61
- console.error(chalk.red("Release doctor failed. Skipping capture and publish."));
62
- const outputDir = path.join(process.cwd(), ".reshot", "output");
63
- fs.ensureDirSync(outputDir);
64
- const resultPath = path.join(outputDir, "ci-result.json");
65
- fs.writeJsonSync(resultPath, ciResult, { spaces: 2 });
66
- process.exitCode = 1;
67
- return ciResult;
68
- }
69
- } catch (error) {
70
- console.error(chalk.red(`Release doctor failed: ${error.message}`));
71
- ciResult.releaseDoctor = { success: false, error: error.message };
72
- const outputDir = path.join(process.cwd(), ".reshot", "output");
73
- fs.ensureDirSync(outputDir);
74
- const resultPath = path.join(outputDir, "ci-result.json");
75
- fs.writeJsonSync(resultPath, ciResult, { spaces: 2 });
76
- process.exitCode = 1;
77
- return ciResult;
78
- }
79
- } else {
80
- ciResult.releaseDoctor = { skipped: true, success: true };
81
- console.log(chalk.gray("Skipping release doctor (--skip-release-doctor)\n"));
82
- }
83
-
84
- // Step 1: Run capture scenarios
85
- console.log(chalk.cyan("━━━ Step 1: Capture ━━━\n"));
86
- try {
87
- const runCommand = require("./run");
88
- const runResult = await runCommand({
89
- headless: true,
90
- noExit: true,
91
- });
92
-
93
- ciResult.run.success = runResult?.success ?? false;
94
- if (runResult?.results) {
95
- ciResult.run.scenariosRun = runResult.results.length;
96
- ciResult.run.scenariosFailed = runResult.results.filter((r) => !r.success).length;
97
- }
98
- } catch (error) {
99
- console.error(chalk.red(`Capture failed: ${error.message}`));
100
- ciResult.run.success = false;
101
- ciResult.run.error = error.message;
102
- }
103
-
104
- // Step 2: Publish (unless --no-publish or capture failed)
105
- if (shouldPublish && ciResult.run.success) {
106
- console.log(chalk.cyan("\n━━━ Step 2: Publish ━━━\n"));
107
- try {
108
- const publishCommand = require("./publish");
109
- const publishResult = await publishCommand({
110
- tag,
111
- message: message || (ciMeta.commitSha ? `CI publish (${ciMeta.commitSha.slice(0, 8)})` : "CI publish"),
112
- dryRun,
113
- force: true, // Skip prompts in CI
114
- outputJson: true,
115
- skipReleaseDoctor: true,
116
- });
117
-
118
- ciResult.publish = {
119
- success: (publishResult?.assetsFailed || 0) === 0,
120
- assetsProcessed: publishResult?.assetsProcessed || 0,
121
- assetsFailed: publishResult?.assetsFailed || 0,
122
- assetsSkipped: publishResult?.assetsSkipped || 0,
123
- viewUrl: publishResult?.viewUrl || null,
124
- };
125
- } catch (error) {
126
- console.error(chalk.red(`Publish failed: ${error.message}`));
127
- ciResult.publish = { success: false, error: error.message };
128
- }
129
- } else if (!shouldPublish) {
130
- console.log(chalk.gray("\n Skipping publish (--no-publish)"));
131
- } else if (!ciResult.run.success) {
132
- console.log(chalk.yellow("\n Skipping publish (capture failed)"));
133
- }
134
-
135
- // Write composite result
136
- const outputDir = path.join(process.cwd(), ".reshot", "output");
137
- fs.ensureDirSync(outputDir);
138
- const resultPath = path.join(outputDir, "ci-result.json");
139
- fs.writeJsonSync(resultPath, ciResult, { spaces: 2 });
140
- console.log(chalk.gray(`\nšŸ“„ CI result written to: ${resultPath}`));
141
-
142
- // Summary
143
- console.log(chalk.cyan("\n━━━ CI Summary ━━━\n"));
144
- if (ciResult.releaseDoctor) {
145
- const doctorIcon = ciResult.releaseDoctor.success ? chalk.green("āœ”") : chalk.red("āœ–");
146
- const doctorLabel = ciResult.releaseDoctor.skipped
147
- ? "skipped"
148
- : ciResult.releaseDoctor.success
149
- ? "passed"
150
- : "failed";
151
- console.log(` ${doctorIcon} Release doctor: ${doctorLabel}`);
152
- }
153
- const runIcon = ciResult.run.success ? chalk.green("āœ”") : chalk.red("āœ–");
154
- console.log(` ${runIcon} Capture: ${ciResult.run.scenariosRun} scenario(s), ${ciResult.run.scenariosFailed} failed`);
155
-
156
- if (ciResult.publish) {
157
- const pubIcon = ciResult.publish.success ? chalk.green("āœ”") : chalk.red("āœ–");
158
- console.log(` ${pubIcon} Publish: ${ciResult.publish.assetsProcessed || 0} asset(s)`);
159
- if (ciResult.publish.viewUrl) {
160
- console.log(chalk.cyan(` šŸ”— ${ciResult.publish.viewUrl}`));
161
- }
162
- }
163
-
164
- console.log();
165
-
166
- // Exit with appropriate code
167
- const overallSuccess =
168
- (ciResult.releaseDoctor?.success ?? true) &&
169
- ciResult.run.success &&
170
- (!ciResult.publish || ciResult.publish.success);
171
- if (!overallSuccess) {
172
- process.exitCode = 1;
173
- }
174
-
175
- return ciResult;
176
- }
177
-
178
- module.exports = ciRunCommand;
@@ -1,288 +0,0 @@
1
- // ci-setup.js - Set up CI/CD integration
2
- const inquirer = require('inquirer');
3
- const chalk = require('chalk');
4
- const fs = require('fs-extra');
5
- const path = require('path');
6
-
7
- const GITHUB_ACTIONS_WORKFLOW = (secretNames) => `name: Reshot Visual Documentation
8
-
9
- on:
10
- push:
11
- branches:
12
- - main
13
- - master
14
-
15
- jobs:
16
- docs:
17
- runs-on: ubuntu-latest
18
-
19
- steps:
20
- - name: Checkout code
21
- uses: actions/checkout@v3
22
-
23
- - name: Set up Node.js
24
- uses: actions/setup-node@v3
25
- with:
26
- node-version: '18'
27
-
28
- - name: Install dependencies
29
- run: npm install
30
-
31
- - name: Install Reshot CLI
32
- run: npm install -g @reshotdev/screenshot
33
-
34
- - name: Install Playwright browsers
35
- run: npx playwright install chromium
36
-
37
- - name: Install ffmpeg
38
- run: sudo apt-get update && sudo apt-get install -y ffmpeg
39
-
40
- # Generate visual assets from reshot.config.json blueprint
41
- # Only runs if features.visuals is enabled for the project
42
- - name: Run Reshot scenarios
43
- env:
44
- RESHOT_API_KEY: \${{ secrets.${secretNames.apiKey} }}
45
- RESHOT_PROJECT_ID: \${{ secrets.${secretNames.projectId} }}
46
- RESHOT_API_BASE_URL: \${{ secrets.${secretNames.baseUrl} }}
47
- TEST_PASSWORD: \${{ secrets.${secretNames.testPassword} }}
48
- run: reshot run
49
-
50
- # Publish three streams to Reshot (respects project feature toggles):
51
- # Stream A: Visual assets (screenshots/videos) - always enabled
52
- # Stream B: Documentation files (if docs feature enabled + configured)
53
- # Stream C: Changelog drafts from commit messages (if changelog feature enabled)
54
- - name: Publish assets to Reshot
55
- env:
56
- RESHOT_API_KEY: \${{ secrets.${secretNames.apiKey} }}
57
- RESHOT_PROJECT_ID: \${{ secrets.${secretNames.projectId} }}
58
- RESHOT_API_BASE_URL: \${{ secrets.${secretNames.baseUrl} }}
59
- TEST_PASSWORD: \${{ secrets.${secretNames.testPassword} }}
60
- run: reshot publish
61
-
62
- - name: Upload artifacts (optional)
63
- uses: actions/upload-artifact@v3
64
- if: always()
65
- with:
66
- name: reshot-output
67
- path: .reshot/output/
68
- `;
69
-
70
- const CIRCLECI_CONFIG = (secretNames) => `version: 2.1
71
-
72
- jobs:
73
- docs:
74
- docker:
75
- - image: cimg/node:18.0-browsers
76
- environment:
77
- RESHOT_API_KEY: \${${secretNames.apiKey}}
78
- RESHOT_PROJECT_ID: \${${secretNames.projectId}}
79
- RESHOT_API_BASE_URL: \${${secretNames.baseUrl}}
80
- TEST_PASSWORD: \${${secretNames.testPassword}}
81
- steps:
82
- - checkout
83
-
84
- - run:
85
- name: Install dependencies
86
- command: |
87
- npm install
88
- npm install -g @reshotdev/screenshot
89
-
90
- - run:
91
- name: Install Playwright browsers
92
- command: npx playwright install chromium
93
-
94
- - run:
95
- name: Install ffmpeg
96
- command: sudo apt-get update && sudo apt-get install -y ffmpeg
97
-
98
- - run:
99
- name: Run Reshot scenarios
100
- command: reshot run
101
-
102
- - run:
103
- name: Publish assets to Reshot
104
- command: reshot publish
105
-
106
- - store_artifacts:
107
- path: .reshot/output
108
-
109
- workflows:
110
- version: 2
111
- docs:
112
- jobs:
113
- - docs
114
- `;
115
-
116
- const GITLAB_CI_CONFIG = (secretNames) => `stages:
117
- - docs
118
-
119
- docs:
120
- stage: docs
121
- image: node:18
122
-
123
- variables:
124
- RESHOT_API_KEY: \$${secretNames.apiKey}
125
- RESHOT_PROJECT_ID: \$${secretNames.projectId}
126
- RESHOT_API_BASE_URL: \$${secretNames.baseUrl}
127
- TEST_PASSWORD: \$${secretNames.testPassword}
128
-
129
- before_script:
130
- - apt-get update && apt-get install -y ffmpeg
131
- - npm install
132
- - npx playwright install chromium
133
- - npm install -g @reshotdev/screenshot
134
-
135
- script:
136
- - reshot run
137
- - reshot publish
138
-
139
- artifacts:
140
- paths:
141
- - .reshot/output/
142
- expire_in: 1 week
143
-
144
- only:
145
- - main
146
- - master
147
- `;
148
-
149
- async function ciSetupCommand() {
150
- console.log(chalk.cyan('šŸ”§ Setting up CI/CD integration...\n'));
151
-
152
- // Prompt for CI provider
153
- const { provider } = await inquirer.prompt([
154
- {
155
- type: 'list',
156
- name: 'provider',
157
- message: 'Select your CI/CD provider:',
158
- choices: [
159
- { name: 'GitHub Actions', value: 'github' },
160
- { name: 'CircleCI', value: 'circleci' },
161
- { name: 'GitLab CI', value: 'gitlab' }
162
- ]
163
- }
164
- ]);
165
-
166
- // Prompt for secret names
167
- console.log(chalk.cyan('\nEnter the names for your CI secrets:'));
168
- const { apiKeySecret, projectIdSecret, baseUrlSecret, testPasswordSecret } = await inquirer.prompt([
169
- {
170
- type: 'input',
171
- name: 'apiKeySecret',
172
- message: 'API Key secret name:',
173
- default: 'RESHOT_API_KEY'
174
- },
175
- {
176
- type: 'input',
177
- name: 'projectIdSecret',
178
- message: 'Project ID secret name:',
179
- default: 'RESHOT_PROJECT_ID'
180
- },
181
- {
182
- type: 'input',
183
- name: 'baseUrlSecret',
184
- message: 'Base URL secret name:',
185
- default: 'RESHOT_API_BASE_URL'
186
- },
187
- {
188
- type: 'input',
189
- name: 'testPasswordSecret',
190
- message: 'Test password secret name:',
191
- default: 'TEST_PASSWORD'
192
- }
193
- ]);
194
-
195
- const secretNames = {
196
- apiKey: apiKeySecret,
197
- projectId: projectIdSecret,
198
- baseUrl: baseUrlSecret,
199
- testPassword: testPasswordSecret
200
- };
201
-
202
- // Generate workflow file based on provider
203
- let workflowPath;
204
- let workflowContent;
205
-
206
- switch (provider) {
207
- case 'github':
208
- workflowPath = path.join(process.cwd(), '.github', 'workflows', 'reshot.yml');
209
- workflowContent = GITHUB_ACTIONS_WORKFLOW(secretNames);
210
- break;
211
-
212
- case 'circleci':
213
- workflowPath = path.join(process.cwd(), '.circleci', 'config.yml');
214
- workflowContent = CIRCLECI_CONFIG(secretNames);
215
- break;
216
-
217
- case 'gitlab':
218
- workflowPath = path.join(process.cwd(), '.gitlab-ci.yml');
219
- workflowContent = GITLAB_CI_CONFIG(secretNames);
220
- break;
221
- }
222
-
223
- // Check if file already exists
224
- if (fs.existsSync(workflowPath)) {
225
- const { overwrite } = await inquirer.prompt([
226
- {
227
- type: 'confirm',
228
- name: 'overwrite',
229
- message: `${workflowPath} already exists. Overwrite?`,
230
- default: false
231
- }
232
- ]);
233
-
234
- if (!overwrite) {
235
- console.log(chalk.yellow('\n⚠ Setup cancelled. Existing workflow file was not modified.'));
236
- return;
237
- }
238
- }
239
-
240
- // Write workflow file
241
- fs.ensureDirSync(path.dirname(workflowPath));
242
- fs.writeFileSync(workflowPath, workflowContent);
243
-
244
- console.log(chalk.green(`\nāœ” Workflow file created: ${workflowPath}`));
245
-
246
- // Print instructions
247
- console.log(chalk.cyan('\nšŸ“‹ Next Steps:\n'));
248
-
249
- switch (provider) {
250
- case 'github':
251
- console.log('1. Go to your GitHub repository settings');
252
- console.log('2. Navigate to ' + chalk.bold('Secrets and variables > Actions'));
253
- console.log('3. Add the following secrets:\n');
254
- console.log(` ${chalk.bold(secretNames.apiKey)} (Project API key for CLI uploads)`);
255
- console.log(` ${chalk.bold(secretNames.projectId)} (Project ID for metadata)`);
256
- console.log(` ${chalk.bold(secretNames.baseUrl)} (API base URL, e.g. https://api.reshot.dev/api)`);
257
- console.log(` ${chalk.bold(secretNames.testPassword)} (Any additional test credential you reference)`);
258
- console.log('\n4. Commit and push the workflow file to trigger the action');
259
- break;
260
-
261
- case 'circleci':
262
- console.log('1. Go to your CircleCI project settings');
263
- console.log('2. Navigate to ' + chalk.bold('Environment Variables'));
264
- console.log('3. Add the following variables:\n');
265
- console.log(` ${chalk.bold(secretNames.apiKey)}`);
266
- console.log(` ${chalk.bold(secretNames.projectId)}`);
267
- console.log(` ${chalk.bold(secretNames.baseUrl)}`);
268
- console.log(` ${chalk.bold(secretNames.testPassword)}`);
269
- console.log('\n4. Commit and push the config file to trigger the pipeline');
270
- break;
271
-
272
- case 'gitlab':
273
- console.log('1. Go to your GitLab project settings');
274
- console.log('2. Navigate to ' + chalk.bold('CI/CD > Variables'));
275
- console.log('3. Add the following variables:\n');
276
- console.log(` ${chalk.bold(secretNames.apiKey)}`);
277
- console.log(` ${chalk.bold(secretNames.projectId)}`);
278
- console.log(` ${chalk.bold(secretNames.baseUrl)}`);
279
- console.log(` ${chalk.bold(secretNames.testPassword)}`);
280
- console.log('\n4. Commit and push the config file to trigger the pipeline');
281
- break;
282
- }
283
-
284
- console.log();
285
- }
286
-
287
- module.exports = ciSetupCommand;
288
-