Skip to content

Commit dd3d360

Browse files
committed
feat: persist/restore state
1 parent 203d4a7 commit dd3d360

File tree

7 files changed

+69
-33
lines changed

7 files changed

+69
-33
lines changed

.engine_scripts/playwright/actions.js

+1-13
Original file line numberDiff line numberDiff line change
@@ -176,19 +176,7 @@ module.exports = async (context) => {
176176

177177
if (!!action.persist) {
178178
console.log(logPrefix + 'persist:', action.persist);
179-
const states = await browserContext.storageState();
180-
setStorageState(action.persist, states);
179+
await browserContext.storageState({ path: action.path });
181180
}
182181
}
183182
};
184-
185-
function setStorageState(stateName, states) {
186-
const statePath = path.join(process.cwd(), 'states', `${stateName}.yaml`);
187-
const parentDir = path.dirname(statePath);
188-
if (!fs.existsSync(parentDir)) {
189-
fs.mkdirSync(parentDir, { recursive: true });
190-
}
191-
192-
const yaml = YAML.dump(states, { lineWidth: -1, noCompatMode: true });
193-
fs.writeFileSync(statePath, yaml);
194-
}

.gitignore

+2-1
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,5 @@ backstop_data/
44
src/**/*.js
55
src/**/*.d.ts
66
src/**/*.map
7-
*.tsbuildinfo
7+
*.tsbuildinfo
8+
.states/

package-lock.json

+33-4
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+6-6
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@
99
},
1010
"scripts": {
1111
"build": "tsc --project tsconfig.json",
12-
"ref": "node src/index.js -- --command test --ref",
13-
"approve": "node src/index.js -- --command approve",
14-
"test": "node src/index.js -- --command test"
12+
"ref": "tsx src/index.js ref",
13+
"approve": "tsx src/index.js approve",
14+
"test": "tsx src/index.js test"
1515
},
1616
"repository": {
1717
"type": "git",
@@ -31,15 +31,15 @@
3131
"chalk": "^5.4.1",
3232
"js-yaml": "^4.1.0",
3333
"ncp": "^2.0.0",
34-
"slash": "^5.1.0",
35-
"tsx": "^4.19.2"
34+
"slash": "^5.1.0"
3635
},
3736
"devDependencies": {
3837
"@types/backstopjs": "^6.1.3",
3938
"@types/js-yaml": "^4.0.9",
4039
"@types/ncp": "^2.0.8",
4140
"@types/node": "^22.10.5",
4241
"ts-node": "^10.9.2",
42+
"tsx": "^4.19.2",
4343
"typescript": "^5.7.3"
4444
}
45-
}
45+
}

src/config.ts

+11-6
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,12 @@ import { Config, Scenario, ViewportNext } from 'backstopjs';
33
import { createScenario } from './scenarios.js';
44
import path from 'path';
55
import { getFlagArg, getStringArg, parseDataFromFile, getLibraryPath } from './helpers.js';
6-
import { TestSuiteModel, ScenarioModel } from './types.js';
6+
import { TestSuiteModel, ScenarioModel, PersistAction } from './types.js';
77
import chalk from 'chalk';
88
import { exit } from 'process';
99
import YAML from 'js-yaml';
1010
import { getTestUrl } from './replacements.js';
11+
import { getStatePath } from './state.js';
1112

1213
const libraryPath = getLibraryPath();
1314
const engine: 'puppeteer' | 'playwright' = 'playwright';
@@ -126,11 +127,6 @@ function getScenarios(args: string[], testSuite: string, isRef: boolean, globalR
126127
total: data.scenarios.length,
127128
delay: s.delay ?? 1000,
128129
state: s.state ?? data.state,
129-
restore: !data.restore
130-
? s.restore
131-
: !s.restore
132-
? data.restore
133-
: [...(typeof data.restore === 'string' ? [data.restore] : data.restore), ...(typeof s.restore === 'string' ? [s.restore] : s.restore)],
134130
hideSelectors: s.hideSelectors ?? data.hideSelectors,
135131
removeSelectors: s.removeSelectors ?? data.removeSelectors,
136132
useCssOverride: s.useCssOverride ?? data.useCssOverride,
@@ -154,6 +150,14 @@ function getScenarios(args: string[], testSuite: string, isRef: boolean, globalR
154150
opts.restore = opts.restore.filter((value, index, self) => self.indexOf(value) === index);
155151
}
156152

153+
if (opts.actions && Array.isArray(opts.actions)) {
154+
let persistActions = opts.actions.filter((a) => (a as PersistAction).persist) as PersistAction[];
155+
for (const persistAction of persistActions) {
156+
persistAction.path = getStatePath(persistAction.persist as string);
157+
console.log('Persist action: ', persistAction);
158+
}
159+
}
160+
157161
const scenario = createScenario(opts);
158162
scenarios.push(scenario);
159163
});
@@ -193,6 +197,7 @@ export function getConfig(args: string[]): Config {
193197
browser: data?.browser ?? 'chromium',
194198
ignoreHTTPSErrors: data && typeof data?.ignoreSslErrors === 'boolean' ? data.ignoreSslErrors : true,
195199
headless: data?.debug ? undefined : 'new',
200+
storageState: data?.state ? getStatePath(data.state) : undefined,
196201
},
197202
asyncCaptureLimit: data?.asyncCaptureLimit ?? 5,
198203
asyncCompareLimit: data?.asyncCompareLimit ?? 50,

src/state.ts

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import fs from 'fs';
2+
import path from 'path';
3+
4+
export function getStatePath(stateName: string) {
5+
const stateFolder = path.join(process.cwd(), '.states');
6+
if (!fs.existsSync(stateFolder)) {
7+
fs.mkdirSync(stateFolder, { recursive: true });
8+
}
9+
10+
return path.join(stateFolder, `${stateName}.json`);
11+
}

0 commit comments

Comments
 (0)