@applitools/eyes-playwright 1.29.4 → 1.30.0

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/CHANGELOG.md CHANGED
@@ -1,5 +1,75 @@
1
1
  # Changelog
2
2
 
3
+ ## [1.30.0](https://github.com/Applitools-Dev/sdk/compare/js/eyes-playwright@1.29.5...js/eyes-playwright@1.30.0) (2024-10-31)
4
+
5
+
6
+ ### Features
7
+
8
+ * html report for playwright ([#2576](https://github.com/Applitools-Dev/sdk/issues/2576)) ([f93f164](https://github.com/Applitools-Dev/sdk/commit/f93f164a289f5676bcc9d650e5e3d90b8e6a6920))
9
+
10
+
11
+ ### Dependencies
12
+
13
+ * @applitools/snippets bumped to 2.6.0
14
+ #### Features
15
+
16
+ * html report for playwright ([#2576](https://github.com/Applitools-Dev/sdk/issues/2576)) ([f93f164](https://github.com/Applitools-Dev/sdk/commit/f93f164a289f5676bcc9d650e5e3d90b8e6a6920))
17
+ * @applitools/spec-driver-playwright bumped to 1.5.0
18
+ #### Features
19
+
20
+ * html report for playwright ([#2576](https://github.com/Applitools-Dev/sdk/issues/2576)) ([f93f164](https://github.com/Applitools-Dev/sdk/commit/f93f164a289f5676bcc9d650e5e3d90b8e6a6920))
21
+
22
+
23
+
24
+ * @applitools/core-base bumped to 1.19.0
25
+ #### Features
26
+
27
+ * html report for playwright ([#2576](https://github.com/Applitools-Dev/sdk/issues/2576)) ([f93f164](https://github.com/Applitools-Dev/sdk/commit/f93f164a289f5676bcc9d650e5e3d90b8e6a6920))
28
+ * @applitools/core bumped to 4.22.0
29
+ #### Features
30
+
31
+ * html report for playwright ([#2576](https://github.com/Applitools-Dev/sdk/issues/2576)) ([f93f164](https://github.com/Applitools-Dev/sdk/commit/f93f164a289f5676bcc9d650e5e3d90b8e6a6920))
32
+
33
+
34
+
35
+ * @applitools/dom-snapshot bumped to 4.11.5
36
+
37
+ * @applitools/driver bumped to 1.19.5
38
+
39
+ * @applitools/spec-driver-webdriver bumped to 1.1.17
40
+
41
+ * @applitools/spec-driver-selenium bumped to 1.5.88
42
+
43
+ * @applitools/spec-driver-puppeteer bumped to 1.4.17
44
+
45
+ * @applitools/screenshoter bumped to 3.9.3
46
+
47
+ * @applitools/nml-client bumped to 1.8.15
48
+
49
+ * @applitools/ec-client bumped to 1.9.11
50
+
51
+ * @applitools/eyes bumped to 1.26.0
52
+ #### Features
53
+
54
+ * html report for playwright ([#2576](https://github.com/Applitools-Dev/sdk/issues/2576)) ([f93f164](https://github.com/Applitools-Dev/sdk/commit/f93f164a289f5676bcc9d650e5e3d90b8e6a6920))
55
+
56
+
57
+
58
+
59
+ ## [1.29.5](https://github.com/Applitools-Dev/sdk/compare/js/eyes-playwright@1.29.4...js/eyes-playwright@1.29.5) (2024-10-29)
60
+
61
+
62
+ ### Dependencies
63
+
64
+ * @applitools/screenshoter bumped to 3.9.2
65
+ #### Bug Fixes
66
+
67
+ * test in screenshoter web ([f068dbe](https://github.com/Applitools-Dev/sdk/commit/f068dbe9036163fb3e316411cfd9f47a226d7c9c))
68
+ * @applitools/core bumped to 4.21.2
69
+
70
+ * @applitools/eyes bumped to 1.25.1
71
+
72
+
3
73
  ## [1.29.4](https://github.com/Applitools-Dev/sdk/compare/js/eyes-playwright@1.29.3...js/eyes-playwright@1.29.4) (2024-10-21)
4
74
 
5
75
 
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const plugin_node_resolve_1 = __importDefault(require("@rollup/plugin-node-resolve"));
7
+ const plugin_commonjs_1 = __importDefault(require("@rollup/plugin-commonjs"));
8
+ const config = {
9
+ input: 'src/fixture/reportRenderer.js',
10
+ output: {
11
+ dir: 'dist/fixture',
12
+ format: 'cjs',
13
+ },
14
+ plugins: [(0, plugin_node_resolve_1.default)({ browser: true }), (0, plugin_commonjs_1.default)()],
15
+ };
16
+ exports.default = config;
@@ -0,0 +1,216 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
4
+ if (k2 === undefined) k2 = k;
5
+ var desc = Object.getOwnPropertyDescriptor(m, k);
6
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
7
+ desc = { enumerable: true, get: function() { return m[k]; } };
8
+ }
9
+ Object.defineProperty(o, k2, desc);
10
+ }) : (function(o, m, k, k2) {
11
+ if (k2 === undefined) k2 = k;
12
+ o[k2] = m[k];
13
+ }));
14
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
15
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
16
+ }) : function(o, v) {
17
+ o["default"] = v;
18
+ });
19
+ var __importStar = (this && this.__importStar) || function (mod) {
20
+ if (mod && mod.__esModule) return mod;
21
+ var result = {};
22
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
23
+ __setModuleDefault(result, mod);
24
+ return result;
25
+ };
26
+ var __importDefault = (this && this.__importDefault) || function (mod) {
27
+ return (mod && mod.__esModule) ? mod : { "default": mod };
28
+ };
29
+ Object.defineProperty(exports, "__esModule", { value: true });
30
+ const fs_1 = __importStar(require("fs"));
31
+ const path_1 = __importDefault(require("path"));
32
+ const prompts_1 = require("@inquirer/prompts");
33
+ const yargs_1 = __importDefault(require("yargs/yargs"));
34
+ const utils = __importStar(require("@applitools/utils"));
35
+ const chalk_1 = __importDefault(require("chalk"));
36
+ const { hideBin } = require('yargs/helpers');
37
+ (0, yargs_1.default)(hideBin(process.argv))
38
+ .command({
39
+ command: 'run-example',
40
+ handler: handleError(runExample),
41
+ })
42
+ .command({
43
+ command: '*',
44
+ builder: yargs => {
45
+ const args = yargs.options({
46
+ apiKey: {
47
+ describe: "Your Applitools Team's API key (here's how to obtain it: https://applitools.com/docs/topics/overview/obtain-api-key.html)",
48
+ type: 'string',
49
+ },
50
+ serverUrl: { describe: 'Your Eyes dedicated cloud server URL', type: 'string' },
51
+ });
52
+ return args;
53
+ },
54
+ handler: handleError(init),
55
+ })
56
+ .help()
57
+ .parse();
58
+ function handleError(asyncFunc) {
59
+ return async (...args) => asyncFunc(...args).catch((err) => {
60
+ if (err.name === 'ExitPromptError') {
61
+ log('See you next time!');
62
+ }
63
+ else {
64
+ error(`Error while setting up Eyes: ${err.message}`);
65
+ }
66
+ process.exit(1);
67
+ });
68
+ }
69
+ async function init(args) {
70
+ log(chalk_1.default.yellow('Setting up Eyes-Playwright fixture and reporter for your project:'));
71
+ let wroteGray = false;
72
+ const playwrightConfig = await fs_1.promises.readFile('playwright.config.ts', 'utf-8');
73
+ await updatePlaywrightConfig();
74
+ await createExampleTest();
75
+ await updateTestFiles();
76
+ printPostlude();
77
+ async function updatePlaywrightConfig() {
78
+ var _a, _b;
79
+ if (!/EyesFixture/.test(playwrightConfig)) {
80
+ const apiKey = (_a = args.apiKey) !== null && _a !== void 0 ? _a : (await (0, prompts_1.input)({
81
+ message: 'Enter your API key (https://applitools.com/docs/topics/overview/obtain-api-key.html):',
82
+ }));
83
+ const serverUrl = (_b = args.serverUrl) !== null && _b !== void 0 ? _b : (await (0, prompts_1.input)({ message: 'Enter your Eyes server URL (the default is https://eyes.applitools.com):' }));
84
+ const apiKeyStr = apiKey ? `apiKey: '${apiKey}'` : `// apiKey: ''`;
85
+ const serverUrlStr = serverUrl ? `serverUrl: '${serverUrl}'` : `// serverUrl: 'https://eyes.applitools.com'`;
86
+ const newPlaywrightConfig = "import { EyesFixture } from '@applitools/eyes-playwright/fixture';\n" +
87
+ playwrightConfig
88
+ .replace(/export default defineConfig\({/, 'export default defineConfig<EyesFixture>({')
89
+ .replace(/(use: {)/, `$1
90
+ /* Configuration for Eyes VisualAI */
91
+ eyesConfig: {
92
+ /* The following and other configuration parameters are documented at: <url> */
93
+ ${apiKeyStr}, // alternatively, set this via environment variable APPLITOOLS_API_KEY
94
+ ${serverUrlStr},
95
+
96
+ // failTestsOnDiff: false,
97
+ // appName: 'My App',
98
+ // matchLevel: 'Strict',
99
+ // batch: { name: 'My Batch' },
100
+ // proxy: {url: 'http://127.0.0.1:8888'},
101
+ // stitchMode: 'CSS',
102
+ // matchTimeout: 0,
103
+ // waitBeforeScreenshots: 50,
104
+ // saveNewTests: true,
105
+ },
106
+ `)
107
+ .replace(/reporter: 'html'/, "reporter: '@applitools/eyes-playwright/reporter'");
108
+ await fs_1.promises.writeFile('playwright.config.ts', newPlaywrightConfig);
109
+ log('');
110
+ log(chalk_1.default.gray('Updating playwright.config.ts with Eyes configuration'));
111
+ log(chalk_1.default.gray('Updating playwright.config.ts with Eyes HTML reporter'));
112
+ wroteGray = true;
113
+ }
114
+ }
115
+ async function createExampleTest() {
116
+ if (!fs_1.default.existsSync('./eyes-examples')) {
117
+ if (!wroteGray) {
118
+ log('');
119
+ wroteGray = true;
120
+ }
121
+ log(chalk_1.default.gray('Creating eyes-examples folder'));
122
+ await fs_1.promises.mkdir('./eyes-examples');
123
+ await fs_1.promises.copyFile(path_1.default.join(__dirname, 'example', 'playwright-website.spec.ts'), './eyes-examples/playwright-website.spec.ts');
124
+ }
125
+ }
126
+ async function updateTestFiles() {
127
+ const testDirMatch = playwrightConfig.match(/testDir\s*:\s*['"]([^'"]+)['"]/);
128
+ if (testDirMatch) {
129
+ const testDir = testDirMatch[1];
130
+ await forEachFile(path_1.default.resolve(testDir), async (filePath) => {
131
+ const testContent = await fs_1.promises.readFile(filePath, 'utf-8');
132
+ await fs_1.promises.writeFile(filePath, testContent.replace(/import { test, expect } from '@playwright\/test'/, `import { test, expect } from '@applitools/eyes-playwright/fixture'`));
133
+ });
134
+ }
135
+ else {
136
+ log(chalk_1.default.yellow('Cannot automatically set up "import {test, expect} from \'@applitools/eyes-playwright/fixture\'" - Could not find testDir from configruation.'));
137
+ }
138
+ }
139
+ function printPostlude() {
140
+ log('');
141
+ if (wroteGray) {
142
+ log(chalk_1.default.green('✔ Success!'), chalk_1.default.bold('Eyes-Playwright fixture and reporter are now set up!'));
143
+ }
144
+ else {
145
+ log(chalk_1.default.cyan('✔ Good news!'), chalk_1.default.bold('Eyes-Playwright is already properly configured!'));
146
+ }
147
+ log('');
148
+ log('Try out the example test by running the following:');
149
+ log('');
150
+ log(chalk_1.default.cyan(' npx eyes-setup run-example'));
151
+ log('');
152
+ log('👀 Tests that are already performing visual tests with expect(page).toHaveScreenshot() now automatically use Eyes');
153
+ log('');
154
+ log("👀 The Eyes HTML reporter extends Playwright's HTML reporter with improved side by side visual comparison");
155
+ log('');
156
+ log('Visit <Eyes docs> for more information.');
157
+ }
158
+ }
159
+ async function runExample() {
160
+ const playwrightTmpConfigPath = './eyes-examples/playwright.tmp.config.ts';
161
+ const playwrightTmpExists = fs_1.default.existsSync(playwrightTmpConfigPath);
162
+ await writeTmpPlaywrightConfig();
163
+ await runPlaywrightCommand();
164
+ await cleanupTmpPlaywrightConfig();
165
+ async function writeTmpPlaywrightConfig() {
166
+ if (!playwrightTmpExists) {
167
+ const playwrighConfig = await fs_1.promises.readFile('./playwright.config.ts', 'utf-8');
168
+ const apikeyMatch = playwrighConfig.match(/apiKey: (.+)/);
169
+ const apiKey = apikeyMatch ? apikeyMatch[1] : undefined;
170
+ const serverUrlMatch = playwrighConfig.match(/serverUrl: (.+)/);
171
+ const serverUrl = serverUrlMatch ? serverUrlMatch[1] : undefined;
172
+ const playwrightTmpConfig = `import { defineConfig, devices } from '@playwright/test';
173
+ import { EyesFixture } from '@applitools/eyes-playwright/fixture';
174
+ export default defineConfig<EyesFixture>({
175
+ testDir: '.',
176
+ outputDir: './test-results',
177
+ reporter: [['@applitools/eyes-playwright/reporter', {open: 'always', outputFolder: './eyes-playwright-report'}]],
178
+ use: {
179
+ eyesConfig: {
180
+ apiKey: ${apiKey !== null && apiKey !== void 0 ? apiKey : ''},
181
+ serverUrl: ${serverUrl !== null && serverUrl !== void 0 ? serverUrl : ''}
182
+ }
183
+ }
184
+ })`;
185
+ await fs_1.promises.writeFile(playwrightTmpConfigPath, playwrightTmpConfig);
186
+ }
187
+ }
188
+ async function cleanupTmpPlaywrightConfig() {
189
+ if (!playwrightTmpExists) {
190
+ await fs_1.promises.unlink(playwrightTmpConfigPath);
191
+ }
192
+ }
193
+ async function runPlaywrightCommand() {
194
+ await utils.process.sh(`npx playwright test --config ${playwrightTmpConfigPath}`, {
195
+ spawnOptions: { stdio: 'inherit' },
196
+ });
197
+ }
198
+ }
199
+ function log(...args) {
200
+ console.log(...args); // eslint-disable-line no-console
201
+ }
202
+ function error(...args) {
203
+ console.error(...args); // eslint-disable-line no-console
204
+ }
205
+ async function forEachFile(folderPath, func) {
206
+ const files = await fs_1.promises.readdir(folderPath);
207
+ for (const file of files) {
208
+ const filePath = path_1.default.join(folderPath, file);
209
+ if ((await fs_1.promises.stat(filePath)).isDirectory()) {
210
+ await forEachFile(filePath, func);
211
+ }
212
+ else {
213
+ await func(filePath);
214
+ }
215
+ }
216
+ }
@@ -0,0 +1,75 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ Object.defineProperty(exports, "__esModule", { value: true });
26
+ exports.getBatchName = void 0;
27
+ const child_process_1 = require("child_process");
28
+ const fs = __importStar(require("fs"));
29
+ const os = __importStar(require("os"));
30
+ const utils = __importStar(require("@applitools/utils"));
31
+ const path = __importStar(require("path"));
32
+ function getBatchName({ appName }) {
33
+ // Function to execute Git command fallback
34
+ function getGitInfo(command) {
35
+ const tmpFilepath = path.join(os.tmpdir(), utils.general.guid());
36
+ try {
37
+ const stream = fs.openSync(tmpFilepath, 'a');
38
+ (0, child_process_1.execSync)(command, { stdio: ['ignore', stream, stream] });
39
+ return fs.readFileSync(tmpFilepath, 'utf-8').trim();
40
+ }
41
+ catch (error) {
42
+ return null;
43
+ }
44
+ finally {
45
+ if (fs.existsSync(tmpFilepath)) {
46
+ fs.unlinkSync(tmpFilepath);
47
+ }
48
+ }
49
+ }
50
+ const branchName = process.env.BRANCH ||
51
+ process.env.CI_COMMIT_BRANCH ||
52
+ process.env.CI_BRANCH_NAME ||
53
+ process.env.CI_COMMIT_REF_NAME ||
54
+ process.env.CI_BRANCH ||
55
+ process.env.REF_NAME ||
56
+ process.env.BUILD_SOURCEBRANCHNAME || // Azure DevOps
57
+ (process.env.GITHUB_REF ? process.env.GITHUB_REF.replace(/^refs\/heads\//, '') : null) || // GitHub Actions
58
+ process.env.CIRCLE_BRANCH || // CircleCI
59
+ process.env.BITBUCKET_BRANCH || // Bitbucket
60
+ process.env.BUILD_BRANCH || // Jenkins
61
+ getGitInfo('git rev-parse --abbrev-ref HEAD'); // Fallback to Git command
62
+ const commitSHA = process.env.SHA ||
63
+ process.env.GIT_SHA ||
64
+ process.env.CI_COMMIT_SHA ||
65
+ process.env.COMMIT_HASH ||
66
+ process.env.CI_COMMIT_ID ||
67
+ process.env.BUILD_SOURCEVERSION || // Azure DevOps
68
+ process.env.GITHUB_SHA || // GitHub Actions
69
+ process.env.CIRCLE_SHA1 || // CircleCI
70
+ process.env.BITBUCKET_COMMIT || // Bitbucket
71
+ process.env.GIT_COMMIT || // Jenkins
72
+ getGitInfo('git rev-parse HEAD'); // Fallback to Git command
73
+ return [appName, commitSHA, branchName].filter(Boolean).join(' - ');
74
+ }
75
+ exports.getBatchName = getBatchName;
@@ -0,0 +1,66 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.getFinalEyesConfiguration = void 0;
7
+ const name_1 = require("./batch/name");
8
+ const path_1 = __importDefault(require("path"));
9
+ function addConfigurationProperties({ properties = [], testInfo, }) {
10
+ const result = [
11
+ ...properties,
12
+ {
13
+ name: 'Playwright title path',
14
+ value: `${path_1.default.relative(process.cwd(), testInfo.file)}:${testInfo.line} > ${testInfo.titlePath
15
+ .slice(1)
16
+ .join(' > ')}`,
17
+ },
18
+ { name: 'Playwright worker index', value: String(testInfo.workerIndex) },
19
+ { name: 'Playwright parallel index', value: String(testInfo.parallelIndex) },
20
+ ...testInfo.tags.map(tag => ({ name: tag, value: tag })),
21
+ ...testInfo.annotations.map(annotation => ({ name: annotation.type, value: String(annotation.description) })),
22
+ ];
23
+ if (testInfo.config.projects.length > 1) {
24
+ result.push({ name: 'Playwright project name', value: testInfo.project.name });
25
+ }
26
+ if (testInfo.retry > 0) {
27
+ properties.push({ name: 'Playwright retry', value: String(testInfo.retry) });
28
+ }
29
+ if (testInfo.expectedStatus !== 'passed') {
30
+ properties.push({ name: 'Playwright expected status', value: testInfo.expectedStatus });
31
+ }
32
+ return result;
33
+ }
34
+ function addBatchDefaults({ configuration }) {
35
+ var _a, _b, _c, _d;
36
+ const batch = (_a = configuration.batch) !== null && _a !== void 0 ? _a : {};
37
+ (_b = batch.id) !== null && _b !== void 0 ? _b : (batch.id = `generated-${process.ppid}`);
38
+ (_c = batch.name) !== null && _c !== void 0 ? _c : (batch.name = (0, name_1.getBatchName)({ appName: configuration.appName }));
39
+ (_d = batch.properties) !== null && _d !== void 0 ? _d : (batch.properties = []);
40
+ batch.properties.push({ name: 'CI', value: process.env.CI ? 'true' : 'false' });
41
+ batch.properties.push({ name: 'Playwright version', value: require('playwright-core/package.json').version });
42
+ return batch;
43
+ }
44
+ function getFinalEyesConfiguration({ playwrightConfig = {}, projectConfig = {}, eyesConfig = {}, testInfo, }) {
45
+ var _a, _b, _c, _d;
46
+ const configuration = {
47
+ ...playwrightConfig,
48
+ ...projectConfig,
49
+ ...eyesConfig,
50
+ };
51
+ (_a = configuration.appName) !== null && _a !== void 0 ? _a : (configuration.appName = 'My App');
52
+ (_b = configuration.displayName) !== null && _b !== void 0 ? _b : (configuration.displayName = testInfo.title); // by default, the display name won't include the full path
53
+ (_c = configuration.testName) !== null && _c !== void 0 ? _c : (configuration.testName = testInfo.titlePath.join(' > '));
54
+ configuration.properties = addConfigurationProperties({ properties: configuration.properties, testInfo });
55
+ configuration.batch = addBatchDefaults({ configuration });
56
+ (_d = configuration.stitchMode) !== null && _d !== void 0 ? _d : (configuration.stitchMode = 'CSS');
57
+ configuration.forceFullPageScreenshot = true;
58
+ const displayName = typeof configuration.displayName === 'function' ? configuration.displayName(testInfo) : configuration.displayName;
59
+ const testName = typeof configuration.testName === 'function' ? configuration.testName(testInfo) : configuration.testName;
60
+ return {
61
+ ...configuration,
62
+ displayName,
63
+ testName,
64
+ };
65
+ }
66
+ exports.getFinalEyesConfiguration = getFinalEyesConfiguration;
@@ -0,0 +1,18 @@
1
+ import { test } from '@applitools/eyes-playwright/fixture'
2
+
3
+ test('Playwright website', async ({ page, eyes }) => {
4
+ await page.goto('https://playwright.dev/');
5
+
6
+ /* Full page visual check */
7
+ await eyes.check('Home page')
8
+
9
+ const searchBox = page.getByLabel('Search')
10
+
11
+ /* Region visual check - "Search" component in light theme */
12
+ await eyes.check('Search box in light theme', {region: searchBox})
13
+
14
+ await page.getByLabel('Switch between dark and light').click();
15
+
16
+ /* Region visual check - "Search" component in dark theme */
17
+ await eyes.check('Search box in dark theme', {region: searchBox})
18
+ });
@@ -0,0 +1,56 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getEyes = void 0;
4
+ const test_1 = require("@playwright/test");
5
+ const index_1 = require("../index");
6
+ const eyesConfiguration_1 = require("./defaults/eyesConfiguration");
7
+ async function getEyes({ testInfo, eyesConfig, eyesRunner, page, }) {
8
+ var _a, _b, _c, _d, _e;
9
+ if (page.__eyes) {
10
+ return page.__eyes;
11
+ }
12
+ const playwrightConfig = (_c = (_b = ((testInfo.config.configFile
13
+ ? (_a = require(testInfo.config.configFile)) === null || _a === void 0 ? void 0 : _a.default
14
+ : {}))) === null || _b === void 0 ? void 0 : _b.use) === null || _c === void 0 ? void 0 : _c.eyesConfig;
15
+ const projectConfig = testInfo.project.use.eyesConfig;
16
+ const configuration = (0, eyesConfiguration_1.getFinalEyesConfiguration)({
17
+ playwrightConfig,
18
+ projectConfig,
19
+ eyesConfig,
20
+ testInfo,
21
+ });
22
+ const eyes = new index_1.Eyes(eyesRunner, {
23
+ // batches are closed automatically after some time, and closing batch from one process might make another process to open a new batch when it's not neccessary.
24
+ // therefore, we decides to set dontCloseBatches to true. If the user wants to see a notification after the batch is closed, we expect them to use our
25
+ // custom playwright reporter, or to sent the notification manually in their CI pipeline
26
+ dontCloseBatches: true,
27
+ ...configuration,
28
+ });
29
+ addLogHandlers(eyes, (_e = (_d = eyesConfig.logConfig) !== null && _d !== void 0 ? _d : projectConfig === null || projectConfig === void 0 ? void 0 : projectConfig.logConfig) !== null && _e !== void 0 ? _e : playwrightConfig === null || playwrightConfig === void 0 ? void 0 : playwrightConfig.logConfig, testInfo);
30
+ eyes.open = makeStep('eyes.open', eyes.open.bind(eyes));
31
+ eyes.check = makeStep('eyes.check', eyes.check.bind(eyes));
32
+ eyes.close = makeStep('eyes.close', eyes.close.bind(eyes));
33
+ eyes.closeAsync = makeStep('eyes.closeAsync (without exception)', eyes.closeAsync.bind(eyes));
34
+ await eyes.open(page, configuration.appName, configuration.testName);
35
+ page.__eyes = eyes;
36
+ return eyes;
37
+ }
38
+ exports.getEyes = getEyes;
39
+ function makeStep(title, f, { box } = { box: true }) {
40
+ return (async (...args) => {
41
+ return test_1.test.step(title, async () => {
42
+ return await f(...args);
43
+ }, { box });
44
+ });
45
+ }
46
+ function addLogHandlers(eyes, logsConfig, testInfo) {
47
+ if (typeof logsConfig === 'function') {
48
+ addLogHandlers(eyes, logsConfig(testInfo), testInfo);
49
+ }
50
+ else if (Array.isArray(logsConfig)) {
51
+ logsConfig.forEach(logSetting => addLogHandlers(eyes, logSetting, testInfo));
52
+ }
53
+ else if (logsConfig) {
54
+ eyes.setLogHandler(logsConfig);
55
+ }
56
+ }
@@ -0,0 +1,4 @@
1
+ <svg version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox='0 0 16 16' width='16' height='16'>
2
+ <title>link</title>
3
+ <path fillRule='evenodd' d='M10.604 1h4.146a.25.25 0 01.25.25v4.146a.25.25 0 01-.427.177L13.03 4.03 9.28 7.78a.75.75 0 01-1.06-1.06l3.75-3.75-1.543-1.543A.25.25 0 0110.604 1zM3.75 2A1.75 1.75 0 002 3.75v8.5c0 .966.784 1.75 1.75 1.75h8.5A1.75 1.75 0 0014 12.25v-3.5a.75.75 0 00-1.5 0v3.5a.25.25 0 01-.25.25h-8.5a.25.25 0 01-.25-.25v-8.5a.25.25 0 01.25-.25h3.5a.75.75 0 000-1.5h-3.5z'></path>
4
+ </svg>
@@ -0,0 +1,3 @@
1
+ <svg className='octicon' viewBox='0 0 48 48' version='1.1' width='20' height='20' aria-hidden='true'>
2
+ <path xmlns='http://www.w3.org/2000/svg' d='M11.85 32H36.2l-7.35-9.95-6.55 8.7-4.6-6.45ZM7 40q-1.2 0-2.1-.9Q4 38.2 4 37V11q0-1.2.9-2.1Q5.8 8 7 8h34q1.2 0 2.1.9.9.9.9 2.1v26q0 1.2-.9 2.1-.9.9-2.1.9Zm0-29v26-26Zm34 26V11H7v26Z'/>
3
+ </svg>