playwright-cucumber-ts-steps 0.1.0 โ†’ 0.1.1

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.
Files changed (33) hide show
  1. package/dist/actions/clickSteps.js +35 -33
  2. package/dist/actions/cookieSteps.js +7 -5
  3. package/dist/actions/debugSteps.js +5 -3
  4. package/dist/actions/elementFindSteps.js +50 -48
  5. package/dist/actions/inputSteps.js +40 -35
  6. package/dist/actions/interceptionSteps.js +9 -7
  7. package/dist/actions/miscSteps.js +41 -36
  8. package/dist/actions/mouseSteps.js +10 -8
  9. package/dist/actions/scrollSteps.js +7 -5
  10. package/dist/actions/storageSteps.js +10 -8
  11. package/dist/assertions/buttonAndTextVisibilitySteps.js +25 -23
  12. package/dist/assertions/cookieSteps.js +7 -5
  13. package/dist/assertions/elementSteps.js +24 -22
  14. package/dist/assertions/formInputSteps.js +28 -26
  15. package/dist/assertions/interceptionRequestsSteps.js +27 -25
  16. package/dist/assertions/locationSteps.js +17 -15
  17. package/dist/assertions/roleTestIdSteps.js +12 -10
  18. package/dist/assertions/semanticSteps.js +9 -7
  19. package/dist/assertions/storageSteps.js +23 -18
  20. package/dist/assertions/visualSteps.js +41 -36
  21. package/dist/custom_setups/globalLogin.js +10 -5
  22. package/dist/custom_setups/loginHooks.js +30 -25
  23. package/dist/helpers/compareSnapshots.js +15 -9
  24. package/dist/helpers/hooks.js +73 -35
  25. package/dist/helpers/utils/fakerUtils.js +32 -26
  26. package/dist/helpers/utils/index.js +19 -3
  27. package/dist/helpers/utils/optionsUtils.js +18 -8
  28. package/dist/helpers/utils/resolveUtils.js +19 -11
  29. package/dist/helpers/world.js +45 -8
  30. package/dist/iframes/frames.js +4 -2
  31. package/dist/index.js +43 -27
  32. package/dist/register.js +3 -1
  33. package/package.json +2 -2
@@ -1,26 +1,31 @@
1
- import { When, Then } from "@cucumber/cucumber";
2
- import fs from "fs";
3
- import path from "path";
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 cucumber_1 = require("@cucumber/cucumber");
7
+ const fs_1 = __importDefault(require("fs"));
8
+ const path_1 = __importDefault(require("path"));
4
9
  //
5
10
  // ๐Ÿ—ƒ LOCAL STORAGE
6
11
  //
7
- Then("I see local storage item {string}", async function (key) {
12
+ (0, cucumber_1.Then)("I see local storage item {string}", async function (key) {
8
13
  const value = await this.page.evaluate((k) => localStorage.getItem(k), key);
9
14
  if (value === null)
10
15
  throw new Error(`Local storage item "${key}" not found`);
11
16
  });
12
- Then("I do not see local storage item {string}", async function (key) {
17
+ (0, cucumber_1.Then)("I do not see local storage item {string}", async function (key) {
13
18
  const value = await this.page.evaluate((k) => localStorage.getItem(k), key);
14
19
  if (value !== null)
15
20
  throw new Error(`Expected localStorage["${key}"] to be null, but got "${value}"`);
16
21
  });
17
- Then("I see local storage item {string} equals {string}", async function (key, expected) {
22
+ (0, cucumber_1.Then)("I see local storage item {string} equals {string}", async function (key, expected) {
18
23
  const actual = await this.page.evaluate((k) => localStorage.getItem(k), key);
19
24
  if (actual !== expected) {
20
25
  throw new Error(`Expected localStorage["${key}"] to be "${expected}", but got "${actual}"`);
21
26
  }
22
27
  });
23
- Then("I see local storage item {string} contains {string}", async function (key, part) {
28
+ (0, cucumber_1.Then)("I see local storage item {string} contains {string}", async function (key, part) {
24
29
  const value = await this.page.evaluate((k) => localStorage.getItem(k), key);
25
30
  if (!value || !value.includes(part)) {
26
31
  throw new Error(`localStorage["${key}"] does not contain "${part}". Got: "${value}"`);
@@ -29,24 +34,24 @@ Then("I see local storage item {string} contains {string}", async function (key,
29
34
  //
30
35
  // ๐Ÿ—‚ SESSION STORAGE
31
36
  //
32
- Then("I see session storage item {string}", async function (key) {
37
+ (0, cucumber_1.Then)("I see session storage item {string}", async function (key) {
33
38
  const value = await this.page.evaluate((k) => sessionStorage.getItem(k), key);
34
39
  if (value === null)
35
40
  throw new Error(`Session storage item "${key}" not found`);
36
41
  });
37
- Then("I do not see session storage item {string}", async function (key) {
42
+ (0, cucumber_1.Then)("I do not see session storage item {string}", async function (key) {
38
43
  const value = await this.page.evaluate((k) => sessionStorage.getItem(k), key);
39
44
  if (value !== null)
40
45
  throw new Error(`Expected sessionStorage["${key}"] to be null, but got "${value}"`);
41
46
  });
42
- When("I clear all saved session files", async function () {
43
- const authDir = path.resolve("e2e/support/helper/auth");
44
- if (fs.existsSync(authDir)) {
45
- const files = fs.readdirSync(authDir);
47
+ (0, cucumber_1.When)("I clear all saved session files", async function () {
48
+ const authDir = path_1.default.resolve("e2e/support/helper/auth");
49
+ if (fs_1.default.existsSync(authDir)) {
50
+ const files = fs_1.default.readdirSync(authDir);
46
51
  for (const file of files) {
47
- const filePath = path.join(authDir, file);
48
- if (fs.lstatSync(filePath).isFile()) {
49
- fs.unlinkSync(filePath);
52
+ const filePath = path_1.default.join(authDir, file);
53
+ if (fs_1.default.lstatSync(filePath).isFile()) {
54
+ fs_1.default.unlinkSync(filePath);
50
55
  this.log?.(`๐Ÿงน Deleted session file: ${file}`);
51
56
  }
52
57
  }
@@ -55,13 +60,13 @@ When("I clear all saved session files", async function () {
55
60
  this.log?.(`โš ๏ธ Auth directory not found at ${authDir}`);
56
61
  }
57
62
  });
58
- Then("I see session storage item {string} equals {string}", async function (key, expected) {
63
+ (0, cucumber_1.Then)("I see session storage item {string} equals {string}", async function (key, expected) {
59
64
  const actual = await this.page.evaluate((k) => sessionStorage.getItem(k), key);
60
65
  if (actual !== expected) {
61
66
  throw new Error(`Expected sessionStorage["${key}"] to be "${expected}", but got "${actual}"`);
62
67
  }
63
68
  });
64
- Then("I see session storage item {string} contains {string}", async function (key, part) {
69
+ (0, cucumber_1.Then)("I see session storage item {string} contains {string}", async function (key, part) {
65
70
  const value = await this.page.evaluate((k) => sessionStorage.getItem(k), key);
66
71
  if (!value || !value.includes(part)) {
67
72
  throw new Error(`sessionStorage["${key}"] does not contain "${part}". Got: "${value}"`);
@@ -1,67 +1,72 @@
1
- import { Then } from "@cucumber/cucumber";
2
- import pixelmatch from "pixelmatch";
3
- import { PNG } from "pngjs";
4
- import fs from "fs";
5
- import path from "path";
6
- import { expect } from "@playwright/test";
7
- const BASELINE_DIR = path.resolve("e2e/snapshots/baseline");
8
- const CURRENT_DIR = path.resolve("e2e/snapshots/current");
9
- const DIFF_DIR = path.resolve("e2e/snapshots/diff");
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 cucumber_1 = require("@cucumber/cucumber");
7
+ const pixelmatch_1 = __importDefault(require("pixelmatch"));
8
+ const pngjs_1 = require("pngjs");
9
+ const fs_1 = __importDefault(require("fs"));
10
+ const path_1 = __importDefault(require("path"));
11
+ const test_1 = require("@playwright/test");
12
+ const BASELINE_DIR = path_1.default.resolve("e2e/snapshots/baseline");
13
+ const CURRENT_DIR = path_1.default.resolve("e2e/snapshots/current");
14
+ const DIFF_DIR = path_1.default.resolve("e2e/snapshots/diff");
10
15
  function getSnapshotPaths(name) {
11
16
  const safeName = name.replace(/[^a-z0-9]/gi, "_").toLowerCase();
12
17
  return {
13
- baseline: path.join(BASELINE_DIR, `${safeName}.png`),
14
- current: path.join(CURRENT_DIR, `${safeName}.png`),
15
- diff: path.join(DIFF_DIR, `${safeName}.diff.png`),
18
+ baseline: path_1.default.join(BASELINE_DIR, `${safeName}.png`),
19
+ current: path_1.default.join(CURRENT_DIR, `${safeName}.png`),
20
+ diff: path_1.default.join(DIFF_DIR, `${safeName}.diff.png`),
16
21
  };
17
22
  }
18
- Then("I should see the page matches the snapshot {string}", async function (name) {
23
+ (0, cucumber_1.Then)("I should see the page matches the snapshot {string}", async function (name) {
19
24
  const { page } = this;
20
25
  const paths = getSnapshotPaths(name);
21
- fs.mkdirSync(BASELINE_DIR, { recursive: true });
22
- fs.mkdirSync(CURRENT_DIR, { recursive: true });
23
- fs.mkdirSync(DIFF_DIR, { recursive: true });
26
+ fs_1.default.mkdirSync(BASELINE_DIR, { recursive: true });
27
+ fs_1.default.mkdirSync(CURRENT_DIR, { recursive: true });
28
+ fs_1.default.mkdirSync(DIFF_DIR, { recursive: true });
24
29
  await page.screenshot({ path: paths.current, fullPage: true });
25
- if (!fs.existsSync(paths.baseline)) {
26
- fs.copyFileSync(paths.current, paths.baseline);
30
+ if (!fs_1.default.existsSync(paths.baseline)) {
31
+ fs_1.default.copyFileSync(paths.current, paths.baseline);
27
32
  this.log?.(`๐Ÿ“ธ Created baseline snapshot: ${paths.baseline}`);
28
33
  return;
29
34
  }
30
- const baseline = PNG.sync.read(fs.readFileSync(paths.baseline));
31
- const current = PNG.sync.read(fs.readFileSync(paths.current));
35
+ const baseline = pngjs_1.PNG.sync.read(fs_1.default.readFileSync(paths.baseline));
36
+ const current = pngjs_1.PNG.sync.read(fs_1.default.readFileSync(paths.current));
32
37
  const { width, height } = baseline;
33
- const diff = new PNG({ width, height });
34
- const pixelDiff = pixelmatch(baseline.data, current.data, diff.data, width, height, { threshold: 0.1 });
38
+ const diff = new pngjs_1.PNG({ width, height });
39
+ const pixelDiff = (0, pixelmatch_1.default)(baseline.data, current.data, diff.data, width, height, { threshold: 0.1 });
35
40
  if (pixelDiff > 0) {
36
- fs.writeFileSync(paths.diff, PNG.sync.write(diff));
41
+ fs_1.default.writeFileSync(paths.diff, pngjs_1.PNG.sync.write(diff));
37
42
  this.log?.(`โŒ Visual mismatch detected, diff: ${paths.diff}`);
38
43
  }
39
- expect(pixelDiff, "Pixels that differ").toBe(0);
44
+ (0, test_1.expect)(pixelDiff, "Pixels that differ").toBe(0);
40
45
  });
41
- Then("I capture a snapshot of the element {string} as {string}", async function (selector, alias) {
46
+ (0, cucumber_1.Then)("I capture a snapshot of the element {string} as {string}", async function (selector, alias) {
42
47
  const element = this.getScope().locator(selector);
43
- const pathCurrent = path.join(CURRENT_DIR, `${alias}.png`);
44
- fs.mkdirSync(CURRENT_DIR, { recursive: true });
48
+ const pathCurrent = path_1.default.join(CURRENT_DIR, `${alias}.png`);
49
+ fs_1.default.mkdirSync(CURRENT_DIR, { recursive: true });
45
50
  await element.screenshot({ path: pathCurrent });
46
51
  this.log?.(`๐Ÿ“ธ Snapshot for ${selector} saved as ${alias}`);
47
52
  });
48
- Then("The snapshot {string} should match baseline", async function (alias) {
53
+ (0, cucumber_1.Then)("The snapshot {string} should match baseline", async function (alias) {
49
54
  const paths = getSnapshotPaths(alias);
50
- const current = PNG.sync.read(fs.readFileSync(paths.current));
51
- const baseline = fs.existsSync(paths.baseline)
52
- ? PNG.sync.read(fs.readFileSync(paths.baseline))
55
+ const current = pngjs_1.PNG.sync.read(fs_1.default.readFileSync(paths.current));
56
+ const baseline = fs_1.default.existsSync(paths.baseline)
57
+ ? pngjs_1.PNG.sync.read(fs_1.default.readFileSync(paths.baseline))
53
58
  : null;
54
59
  if (!baseline) {
55
- fs.copyFileSync(paths.current, paths.baseline);
60
+ fs_1.default.copyFileSync(paths.current, paths.baseline);
56
61
  this.log?.(`๐Ÿ“ธ Created new baseline for ${alias}`);
57
62
  return;
58
63
  }
59
64
  const { width, height } = baseline;
60
- const diff = new PNG({ width, height });
61
- const pixelDiff = pixelmatch(baseline.data, current.data, diff.data, width, height, { threshold: 0.1 });
65
+ const diff = new pngjs_1.PNG({ width, height });
66
+ const pixelDiff = (0, pixelmatch_1.default)(baseline.data, current.data, diff.data, width, height, { threshold: 0.1 });
62
67
  if (pixelDiff > 0) {
63
- fs.writeFileSync(paths.diff, PNG.sync.write(diff));
68
+ fs_1.default.writeFileSync(paths.diff, pngjs_1.PNG.sync.write(diff));
64
69
  this.log?.(`โš ๏ธ Snapshot mismatch: ${alias}`);
65
70
  }
66
- expect(pixelDiff).toBe(0);
71
+ (0, test_1.expect)(pixelDiff).toBe(0);
67
72
  });
@@ -1,8 +1,13 @@
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 });
1
6
  // global-setup.ts
2
- import { chromium } from "@playwright/test";
3
- import path from "path";
7
+ const test_1 = require("@playwright/test");
8
+ const path_1 = __importDefault(require("path"));
4
9
  async function globalSetup() {
5
- const browser = await chromium.launch();
10
+ const browser = await test_1.chromium.launch();
6
11
  const page = await browser.newPage();
7
12
  // Navigate to login and log in
8
13
  await page.goto(process.env.PLAYWRIGHT_BASE_URL || "http://demoqa.com");
@@ -14,7 +19,7 @@ async function globalSetup() {
14
19
  // Save session to file
15
20
  await page
16
21
  .context()
17
- .storageState({ path: path.resolve(__dirname, "storageState.json") });
22
+ .storageState({ path: path_1.default.resolve(__dirname, "storageState.json") });
18
23
  await browser.close();
19
24
  }
20
- export default globalSetup;
25
+ exports.default = globalSetup;
@@ -1,13 +1,18 @@
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 });
1
6
  // e2e/step_definitions/auth/loginHooks.ts
2
- import { When } from "@cucumber/cucumber";
3
- import { expect } from "@playwright/test";
4
- import path from "path";
5
- import { resolveValue, deriveSessionName, resolveLoginValue, } from "../helpers/utils/resolveUtils";
6
- import fs from "fs";
7
- import { log } from "console";
7
+ const cucumber_1 = require("@cucumber/cucumber");
8
+ const test_1 = require("@playwright/test");
9
+ const path_1 = __importDefault(require("path"));
10
+ const resolveUtils_1 = require("../helpers/utils/resolveUtils");
11
+ const fs_1 = __importDefault(require("fs"));
12
+ const console_1 = require("console");
8
13
  async function tryRestoreSession(world, sessionName) {
9
- const storagePath = path.resolve("e2e/support/helper/auth", `${sessionName}.json`);
10
- if (fs.existsSync(storagePath)) {
14
+ const storagePath = path_1.default.resolve("e2e/support/helper/auth", `${sessionName}.json`);
15
+ if (fs_1.default.existsSync(storagePath)) {
11
16
  await world.context?.addCookies([]);
12
17
  await world.page.context().addInitScript(() => {
13
18
  // preload logic if needed
@@ -23,30 +28,30 @@ async function loginAndSaveSession(world, email, password, sessionName) {
23
28
  if (!baseUrl)
24
29
  throw new Error("Missing BASE_URL in environment");
25
30
  await pageLogin(world, baseUrl, email, password);
26
- const sessionFile = path.resolve("e2e/support/helper/auth", `${sessionName}.json`);
31
+ const sessionFile = path_1.default.resolve("e2e/support/helper/auth", `${sessionName}.json`);
27
32
  await world.page.context().storageState({ path: sessionFile });
28
33
  world.log(`Session saved to ${sessionFile}`);
29
34
  }
30
35
  const loginStep = async function (user, pass) {
31
- const email = resolveValue(user);
32
- const password = resolveValue(pass);
33
- const sessionName = deriveSessionName(email);
36
+ const email = (0, resolveUtils_1.resolveValue)(user);
37
+ const password = (0, resolveUtils_1.resolveValue)(pass);
38
+ const sessionName = (0, resolveUtils_1.deriveSessionName)(email);
34
39
  const restored = await tryRestoreSession(this, sessionName);
35
40
  if (!restored) {
36
41
  await loginAndSaveSession(this, email, password, sessionName);
37
42
  }
38
43
  };
39
- When("I am logged out", async function () {
44
+ (0, cucumber_1.When)("I am logged out", async function () {
40
45
  const { page } = this;
41
46
  await page.goto("/");
42
47
  const url = page.url();
43
48
  if (!url.includes("/login")) {
44
49
  await page.locator("//div[@id=':rti:']//*[name()='svg']").last().click();
45
50
  await page.getByText("Logout").click();
46
- await expect(page.getByText("Log in")).toBeVisible();
51
+ await (0, test_1.expect)(page.getByText("Log in")).toBeVisible();
47
52
  }
48
53
  });
49
- When("I login as a default user", async function () {
54
+ (0, cucumber_1.When)("I login as a default user", async function () {
50
55
  const baseUrl = process.env.BASE_URL;
51
56
  const email = process.env.USER_EMAIL;
52
57
  const password = process.env.USER_PASSWORD;
@@ -56,18 +61,18 @@ When("I login as a default user", async function () {
56
61
  }
57
62
  await pageLogin(this, baseUrl, email, password);
58
63
  });
59
- When("I login with user {string} and password {string}", loginStep);
64
+ (0, cucumber_1.When)("I login with user {string} and password {string}", loginStep);
60
65
  // Given("I login with user {string} and password {string}", loginStep);
61
66
  // Special alias step
62
- When("I login as {string} user", async function (alias) {
63
- const sessionFile = path.resolve("storage", `${alias}User.json`);
67
+ (0, cucumber_1.When)("I login as {string} user", async function (alias) {
68
+ const sessionFile = path_1.default.resolve("storage", `${alias}User.json`);
64
69
  const email = process.env.USER_EMAIL;
65
70
  const password = process.env.USER_PASSWORD;
66
71
  const baseUrl = process.env.BASE_URL;
67
72
  if (!email || !password) {
68
73
  throw new Error("USER_EMAIL or USER_PASSWORD not set in .env");
69
74
  }
70
- if (fs.existsSync(sessionFile)) {
75
+ if (fs_1.default.existsSync(sessionFile)) {
71
76
  await this.context.addCookies([]); // optional reset
72
77
  await this.context.addInitScript(() => { });
73
78
  await this.context.storageState({ path: sessionFile });
@@ -89,10 +94,10 @@ When("I login as {string} user", async function (alias) {
89
94
  await this.context.storageState({ path: sessionFile });
90
95
  this.log(`๐Ÿ’พ Saved session to ${alias}User.json`);
91
96
  });
92
- When("I perform login with:", async function (dataTable) {
97
+ (0, cucumber_1.When)("I perform login with:", async function (dataTable) {
93
98
  const loginData = Object.fromEntries(dataTable.raw());
94
- const email = resolveLoginValue(loginData.email, this);
95
- const password = resolveLoginValue(loginData.password, this) ?? process.env.USER_PASSWORD;
99
+ const email = (0, resolveUtils_1.resolveLoginValue)(loginData.email, this);
100
+ const password = (0, resolveUtils_1.resolveLoginValue)(loginData.password, this) ?? process.env.USER_PASSWORD;
96
101
  if (!email)
97
102
  throw new Error("Missing or invalid email for login");
98
103
  if (!password)
@@ -117,15 +122,15 @@ async function pageLogin(world, baseUrl, email, password) {
117
122
  await page.getByRole("button", { name: "Login" }).click();
118
123
  await page.waitForLoadState("networkidle");
119
124
  if (await page.getByText("Select an account").isVisible()) {
120
- log("Login successful, navigating to accounts page");
125
+ (0, console_1.log)("Login successful, navigating to accounts page");
121
126
  await page.goto(`${baseUrl}/indicina`);
122
127
  }
123
- await expect(page.getByText("Total unique customers")).toBeVisible({
128
+ await (0, test_1.expect)(page.getByText("Total unique customers")).toBeVisible({
124
129
  timeout: 10000,
125
130
  });
126
131
  // โœ… Save session after successful login
127
132
  await page.context().storageState({
128
- path: path.resolve("e2e/support/helper/auth", "session.json"),
133
+ path: path_1.default.resolve("e2e/support/helper/auth", "session.json"),
129
134
  });
130
135
  world.data["loggedIn"] = true;
131
136
  world.log?.("โœ… Logged in and session saved.");
@@ -1,14 +1,20 @@
1
- import fs from "fs";
2
- import pixelmatch from "pixelmatch";
3
- import { PNG } from "pngjs";
4
- export function compareSnapshots({ actualPath, baselinePath, diffPath, threshold = 0.1, }) {
5
- const actual = PNG.sync.read(fs.readFileSync(actualPath));
6
- const baseline = PNG.sync.read(fs.readFileSync(baselinePath));
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.compareSnapshots = compareSnapshots;
7
+ const fs_1 = __importDefault(require("fs"));
8
+ const pixelmatch_1 = __importDefault(require("pixelmatch"));
9
+ const pngjs_1 = require("pngjs");
10
+ function compareSnapshots({ actualPath, baselinePath, diffPath, threshold = 0.1, }) {
11
+ const actual = pngjs_1.PNG.sync.read(fs_1.default.readFileSync(actualPath));
12
+ const baseline = pngjs_1.PNG.sync.read(fs_1.default.readFileSync(baselinePath));
7
13
  if (actual.width !== baseline.width || actual.height !== baseline.height) {
8
14
  throw new Error("Snapshot size mismatch");
9
15
  }
10
- const diff = new PNG({ width: actual.width, height: actual.height });
11
- const numDiffPixels = pixelmatch(actual.data, baseline.data, diff.data, actual.width, actual.height, { threshold });
12
- fs.writeFileSync(diffPath, PNG.sync.write(diff));
16
+ const diff = new pngjs_1.PNG({ width: actual.width, height: actual.height });
17
+ const numDiffPixels = (0, pixelmatch_1.default)(actual.data, baseline.data, diff.data, actual.width, actual.height, { threshold });
18
+ fs_1.default.writeFileSync(diffPath, pngjs_1.PNG.sync.write(diff));
13
19
  return numDiffPixels;
14
20
  }
@@ -1,18 +1,56 @@
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 () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
1
39
  // support/hooks.ts
2
- import { Before, After, BeforeAll, AfterAll, } from "@cucumber/cucumber";
3
- import { chromium, devices } from "playwright";
4
- import * as dotenv from "dotenv";
5
- import fs from "fs";
6
- import path from "path";
7
- import { compareSnapshots } from "./compareSnapshots";
40
+ const cucumber_1 = require("@cucumber/cucumber");
41
+ const playwright_1 = require("playwright");
42
+ const dotenv = __importStar(require("dotenv"));
43
+ const fs_1 = __importDefault(require("fs"));
44
+ const path_1 = __importDefault(require("path"));
45
+ const compareSnapshots_1 = require("./compareSnapshots");
8
46
  dotenv.config();
9
- const SESSION_FILE = path.resolve("e2e/support/helper/auth", "session.json");
10
- const SCREENSHOT_DIR = path.resolve("e2e/screenshots");
11
- const VIDEO_DIR = path.resolve("e2e/videos");
12
- const SNAPSHOT_BASELINE_DIR = path.resolve("e2e/snapshots/baseline");
13
- const SNAPSHOT_DIFF_DIR = path.resolve("e2e/snapshots/diff");
47
+ const SESSION_FILE = path_1.default.resolve("e2e/support/helper/auth", "session.json");
48
+ const SCREENSHOT_DIR = path_1.default.resolve("e2e/screenshots");
49
+ const VIDEO_DIR = path_1.default.resolve("e2e/videos");
50
+ const SNAPSHOT_BASELINE_DIR = path_1.default.resolve("e2e/snapshots/baseline");
51
+ const SNAPSHOT_DIFF_DIR = path_1.default.resolve("e2e/snapshots/diff");
14
52
  let sharedBrowser;
15
- BeforeAll(async () => {
53
+ (0, cucumber_1.BeforeAll)(async () => {
16
54
  const dirsToClean = [
17
55
  VIDEO_DIR,
18
56
  SCREENSHOT_DIR,
@@ -20,8 +58,8 @@ BeforeAll(async () => {
20
58
  ];
21
59
  for (const dir of dirsToClean) {
22
60
  try {
23
- if (fs.existsSync(dir)) {
24
- fs.rmSync(dir, { recursive: true, force: true });
61
+ if (fs_1.default.existsSync(dir)) {
62
+ fs_1.default.rmSync(dir, { recursive: true, force: true });
25
63
  console.log(`๐Ÿงน Cleaned directory: ${dir}`);
26
64
  }
27
65
  }
@@ -29,20 +67,20 @@ BeforeAll(async () => {
29
67
  console.warn(`โš ๏ธ Failed to clean directory ${dir}:`, err);
30
68
  }
31
69
  }
32
- sharedBrowser = await chromium.launch({
70
+ sharedBrowser = await playwright_1.chromium.launch({
33
71
  headless: process.env.HEADLESS !== "false",
34
72
  });
35
73
  console.log("๐Ÿš€ Launched shared browser for all scenarios");
36
74
  });
37
- AfterAll(async () => {
75
+ (0, cucumber_1.AfterAll)(async () => {
38
76
  await sharedBrowser?.close();
39
77
  console.log("๐Ÿงน Closed shared browser after all scenarios");
40
78
  });
41
- Before(async function (scenario) {
79
+ (0, cucumber_1.Before)(async function (scenario) {
42
80
  // ๐Ÿ›ก๏ธ Ensure browser is still usable
43
81
  if (!sharedBrowser || !sharedBrowser.isConnected()) {
44
82
  console.warn("โš ๏ธ Shared browser was disconnected. Restarting...");
45
- sharedBrowser = await chromium.launch({
83
+ sharedBrowser = await playwright_1.chromium.launch({
46
84
  headless: process.env.HEADLESS !== "false",
47
85
  });
48
86
  }
@@ -52,9 +90,9 @@ Before(async function (scenario) {
52
90
  process.env.VISUAL_TEST = "true";
53
91
  const contextOptions = {
54
92
  recordVideo: { dir: VIDEO_DIR },
55
- ...(isMobile ? devices["iPhone 13 Pro"] : {}),
93
+ ...(isMobile ? playwright_1.devices["iPhone 13 Pro"] : {}),
56
94
  };
57
- if (fs.existsSync(SESSION_FILE)) {
95
+ if (fs_1.default.existsSync(SESSION_FILE)) {
58
96
  contextOptions.storageState = SESSION_FILE;
59
97
  this.log?.("โœ… Reusing session from saved file.");
60
98
  }
@@ -66,14 +104,14 @@ Before(async function (scenario) {
66
104
  if (isMobile)
67
105
  this.log?.("๐Ÿ“ฑ Mobile emulation enabled (iPhone 13 Pro)");
68
106
  });
69
- After(async function (scenario) {
107
+ (0, cucumber_1.After)(async function (scenario) {
70
108
  const failed = scenario.result?.status === "FAILED";
71
109
  const name = scenario.pickle.name.replace(/[^a-z0-9]+/gi, "_").toLowerCase();
72
110
  // ๐Ÿ“ธ Screenshot on failure
73
111
  if (failed && this.page) {
74
- const screenshotPath = path.join(SCREENSHOT_DIR, `failed-${name}.png`);
112
+ const screenshotPath = path_1.default.join(SCREENSHOT_DIR, `failed-${name}.png`);
75
113
  try {
76
- fs.mkdirSync(SCREENSHOT_DIR, { recursive: true });
114
+ fs_1.default.mkdirSync(SCREENSHOT_DIR, { recursive: true });
77
115
  await this.page.screenshot({ path: screenshotPath, fullPage: true });
78
116
  console.log(`๐Ÿ–ผ๏ธ Screenshot saved: ${screenshotPath}`);
79
117
  }
@@ -91,14 +129,14 @@ After(async function (scenario) {
91
129
  }
92
130
  if (rawPath) {
93
131
  try {
94
- const finalPath = path.join(VIDEO_DIR, `failed-${name}.webm`);
95
- fs.mkdirSync(VIDEO_DIR, { recursive: true });
132
+ const finalPath = path_1.default.join(VIDEO_DIR, `failed-${name}.webm`);
133
+ fs_1.default.mkdirSync(VIDEO_DIR, { recursive: true });
96
134
  if (failed) {
97
- fs.renameSync(rawPath, finalPath);
135
+ fs_1.default.renameSync(rawPath, finalPath);
98
136
  console.log(`๐ŸŽฅ Video saved: ${finalPath}`);
99
137
  }
100
138
  else {
101
- fs.unlinkSync(rawPath);
139
+ fs_1.default.unlinkSync(rawPath);
102
140
  console.log(`๐Ÿงน Deleted video for passed test: ${rawPath}`);
103
141
  }
104
142
  }
@@ -108,19 +146,19 @@ After(async function (scenario) {
108
146
  }
109
147
  // ๐Ÿงช Visual regression testing
110
148
  if (this.page && process.env.VISUAL_TEST === "true") {
111
- fs.mkdirSync(SNAPSHOT_BASELINE_DIR, { recursive: true });
112
- fs.mkdirSync(SNAPSHOT_DIFF_DIR, { recursive: true });
113
- const baselinePath = path.join(SNAPSHOT_BASELINE_DIR, `${name}.png`);
114
- const actualPath = path.join(SNAPSHOT_DIFF_DIR, `${name}.actual.png`);
115
- const diffPath = path.join(SNAPSHOT_DIFF_DIR, `${name}.diff.png`);
149
+ fs_1.default.mkdirSync(SNAPSHOT_BASELINE_DIR, { recursive: true });
150
+ fs_1.default.mkdirSync(SNAPSHOT_DIFF_DIR, { recursive: true });
151
+ const baselinePath = path_1.default.join(SNAPSHOT_BASELINE_DIR, `${name}.png`);
152
+ const actualPath = path_1.default.join(SNAPSHOT_DIFF_DIR, `${name}.actual.png`);
153
+ const diffPath = path_1.default.join(SNAPSHOT_DIFF_DIR, `${name}.diff.png`);
116
154
  await this.page.screenshot({ path: actualPath, fullPage: true });
117
- if (!fs.existsSync(baselinePath)) {
118
- fs.copyFileSync(actualPath, baselinePath);
155
+ if (!fs_1.default.existsSync(baselinePath)) {
156
+ fs_1.default.copyFileSync(actualPath, baselinePath);
119
157
  console.log(`๐Ÿ“ธ Created baseline image: ${baselinePath}`);
120
158
  }
121
159
  else {
122
160
  try {
123
- const diffPixels = compareSnapshots({
161
+ const diffPixels = (0, compareSnapshots_1.compareSnapshots)({
124
162
  actualPath,
125
163
  baselinePath,
126
164
  diffPath,