@elliemae/smoked-suite 26.2.16 → 26.2.18

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.
@@ -0,0 +1,246 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var base_test_exports = {};
20
+ __export(base_test_exports, {
21
+ BaseTest: () => BaseTest
22
+ });
23
+ module.exports = __toCommonJS(base_test_exports);
24
+ var import_test = require("@playwright/test");
25
+ var import_auth = require("../auth/index.js");
26
+ var import_page_setup = require("../page-setup/index.js");
27
+ var import_monocartCoverage = require("../monocartCoverage/index.js");
28
+ const DEFAULT_NAVIGATION_TIMEOUT = 6e4;
29
+ const DEFAULT_ELEMENT_TIMEOUT = 5e3;
30
+ class BaseTest {
31
+ auth = new import_auth.AuthManager();
32
+ pageSetup = new import_page_setup.PageSetup();
33
+ /** Whether sessionStorage was injected via `addInitScript`. */
34
+ sessionInjectedViaInitScript = false;
35
+ /** Top-level Playwright page. Used for navigation, auth, and interaction. */
36
+ page;
37
+ /**
38
+ * Alias for {@link page}. Available after calling a navigation
39
+ * method such as {@link goToEmAdminUI}. Pass to page objects
40
+ * via a callback: `() => this.appFrame`.
41
+ */
42
+ appFrame;
43
+ // ─── Credentials ─────────────────────────────────────────────────────────────
44
+ /**
45
+ * Return the credentials used for the encw login flow.
46
+ *
47
+ * Reads from environment variables with local-development defaults:
48
+ *
49
+ * | Variable | Default |
50
+ * |---------------------|---------------|
51
+ * | `ENCW_INSTANCE_ID` | `BE11226875` |
52
+ * | `ENCW_USER_ID` | `admin` |
53
+ * | `ENCW_PASSWORD` | `Password#!23` |
54
+ *
55
+ * Override this method to supply different credentials.
56
+ */
57
+ getCredentials() {
58
+ return {
59
+ instanceId: process.env.ENCW_INSTANCE_ID ?? "BE11226875",
60
+ username: process.env.ENCW_USER_ID ?? "admin",
61
+ password: process.env.ENCW_PASSWORD ?? "Password#!23"
62
+ };
63
+ }
64
+ // ─── Auth orchestration ──────────────────────────────────────────────────────
65
+ /**
66
+ * Ensure the browser has a valid encw session.
67
+ *
68
+ * - First test in a worker: performs the full login flow and
69
+ * snapshots session storage.
70
+ * - Subsequent tests: session is injected during
71
+ * {@link navigateToApp}.
72
+ *
73
+ * This method does **not** navigate to any app route.
74
+ */
75
+ async ensureAuth() {
76
+ await this.pageSetup.apply(this.page);
77
+ if (!this.auth.hasValidAuth() && import_auth.AuthManager.loadFromFile()) {
78
+ const state = import_auth.AuthManager.getAuthState();
79
+ if (state) {
80
+ await this.page.addInitScript((entries) => {
81
+ for (const [key, value] of Object.entries(entries)) {
82
+ sessionStorage.setItem(key, value);
83
+ }
84
+ }, state.sessionEntries);
85
+ this.sessionInjectedViaInitScript = true;
86
+ }
87
+ }
88
+ if (this.auth.hasValidAuth()) {
89
+ return;
90
+ }
91
+ await this.auth.login(this.page, this.getCredentials());
92
+ await this.auth.capture(this.page);
93
+ }
94
+ // ─── App navigation ────────────────────────────────────────────────────────
95
+ /**
96
+ * Navigate to an application route.
97
+ *
98
+ * Handles auth injection (for cached sessions) and page navigation.
99
+ * @param route - URL path to navigate to (e.g. `/admin`).
100
+ */
101
+ async navigateToApp(route) {
102
+ if (this.sessionInjectedViaInitScript) {
103
+ await this.page.goto(route, { waitUntil: "domcontentloaded" });
104
+ return;
105
+ }
106
+ if (this.auth.hasValidAuth()) {
107
+ await this.page.goto("", { waitUntil: "domcontentloaded" });
108
+ await this.auth.inject(this.page);
109
+ }
110
+ await this.page.goto(route, {
111
+ waitUntil: "domcontentloaded"
112
+ });
113
+ }
114
+ /**
115
+ * Log in to encw and navigate to the **em-admin-ui** app.
116
+ * After this method returns, {@link page} is on the admin route.
117
+ */
118
+ async goToEmAdminUI() {
119
+ await this.navigateToApp("/admin");
120
+ }
121
+ /**
122
+ * Log in to encw and navigate to the **pipeline** app.
123
+ * After this method returns, {@link page} is on the pipeline route.
124
+ */
125
+ async goToPipeline() {
126
+ await this.navigateToApp("/pipeline");
127
+ }
128
+ // ─── Navigation helpers ──────────────────────────────────────────────────────
129
+ /**
130
+ * Navigate to a URL path.
131
+ * @param path - Absolute URL path (e.g. `/admin/oneadmin/migrate`).
132
+ * @param options - Navigation options forwarded to Playwright.
133
+ */
134
+ async goto(path, options = {}) {
135
+ const {
136
+ waitUntil = "domcontentloaded",
137
+ timeout = DEFAULT_NAVIGATION_TIMEOUT
138
+ } = options;
139
+ await this.page.goto(path, { waitUntil, timeout });
140
+ }
141
+ /**
142
+ * Wait for an element to be visible on the page.
143
+ * @param selector - CSS selector.
144
+ * @param options - Timeout and expected state.
145
+ * @param options.timeout
146
+ * @param options.state
147
+ */
148
+ async waitForElement(selector, options = {}) {
149
+ const { timeout = DEFAULT_ELEMENT_TIMEOUT, state = "visible" } = options;
150
+ await this.page.locator(selector).waitFor({ timeout, state });
151
+ }
152
+ /** Playwright's `expect` — exposed for assertions inside test methods. */
153
+ get expect() {
154
+ return import_test.expect;
155
+ }
156
+ // ─── Lifecycle hooks ─────────────────────────────────────────────────────────
157
+ /**
158
+ * Called once before all tests in a describe block.
159
+ * Override in a subclass to add one-time setup logic.
160
+ * Note: `this.page` is not available in this hook.
161
+ */
162
+ async beforeAll() {
163
+ }
164
+ /**
165
+ * Called once after all tests in a describe block.
166
+ * Override in a subclass to add one-time teardown logic.
167
+ * Note: `this.page` is not available in this hook.
168
+ */
169
+ async afterAll() {
170
+ }
171
+ /**
172
+ * Called before each test. Override in a subclass to add setup
173
+ * logic (e.g. `await this.goToEmAdminUI()`).
174
+ */
175
+ async beforeEach() {
176
+ }
177
+ /** Called after each test. Override to add teardown logic. */
178
+ async afterEach() {
179
+ }
180
+ // ─── Test runner ─────────────────────────────────────────────────────────────
181
+ static toReadableTitle(methodName) {
182
+ const withoutPrefix = methodName.replace(/^test/, "");
183
+ return withoutPrefix.replace(/([A-Z])/g, " $1").toLowerCase().trim();
184
+ }
185
+ /**
186
+ * Register all `test*` methods in this class with Playwright.
187
+ *
188
+ * Call once at module level after the class definition:
189
+ * ```ts
190
+ * class MySpec extends BaseTest { ... }
191
+ * MySpec.run();
192
+ * ```
193
+ */
194
+ static run() {
195
+ const TestClass = this;
196
+ const className = TestClass.name;
197
+ const proto = TestClass.prototype;
198
+ const testMethods = Object.getOwnPropertyNames(proto).filter(
199
+ (name) => name.startsWith("test") && typeof proto[name] === "function"
200
+ );
201
+ if (testMethods.length === 0) {
202
+ console.warn(
203
+ `No test methods found in ${className}. Test methods must start with 'test'.`
204
+ );
205
+ return;
206
+ }
207
+ import_test.test.describe(className, () => {
208
+ let instance;
209
+ import_test.test.beforeAll(async () => {
210
+ (0, import_monocartCoverage.startCoverage)();
211
+ instance = new TestClass();
212
+ if (typeof instance.beforeAll === "function") {
213
+ await instance.beforeAll();
214
+ }
215
+ });
216
+ import_test.test.beforeEach(async ({ page }) => {
217
+ instance = new TestClass();
218
+ instance.page = page;
219
+ instance.appFrame = page;
220
+ await instance.ensureAuth();
221
+ await (0, import_monocartCoverage.trackPage)(page);
222
+ if (typeof instance.beforeEach === "function") {
223
+ await instance.beforeEach();
224
+ }
225
+ });
226
+ import_test.test.afterEach(async () => {
227
+ if (typeof instance.afterEach === "function") {
228
+ await instance.afterEach();
229
+ }
230
+ await (0, import_monocartCoverage.untrackPage)(instance.page);
231
+ });
232
+ import_test.test.afterAll(async () => {
233
+ await (0, import_monocartCoverage.stopCoverage)();
234
+ if (typeof instance.afterAll === "function") {
235
+ await instance.afterAll();
236
+ }
237
+ });
238
+ for (const methodName of testMethods) {
239
+ const title = TestClass.toReadableTitle(methodName);
240
+ (0, import_test.test)(title, async () => {
241
+ await instance[methodName]();
242
+ });
243
+ }
244
+ });
245
+ }
246
+ }
package/dist/cjs/index.js CHANGED
@@ -30,6 +30,7 @@ var index_exports = {};
30
30
  __export(index_exports, {
31
31
  AuthManager: () => import_auth.AuthManager,
32
32
  BasePage: () => import_base_page.BasePage,
33
+ BaseTest: () => import_base_test.BaseTest,
33
34
  PageSetup: () => import_page_setup.PageSetup,
34
35
  createBrowserStackConfig: () => import_browserstack.createBrowserStackConfig,
35
36
  createPlaywrightConfig: () => import_playwright_config.createPlaywrightConfig,
@@ -38,6 +39,7 @@ __export(index_exports, {
38
39
  writeBrowserStackConfig: () => import_browserstack.writeBrowserStackConfig
39
40
  });
40
41
  module.exports = __toCommonJS(index_exports);
42
+ var import_base_test = require("./base-test/index.js");
41
43
  var import_base_page = require("./base-page/index.js");
42
44
  var import_auth = require("./auth/index.js");
43
45
  var import_page_setup = require("./page-setup/index.js");
@@ -35,10 +35,10 @@ var path = __toESM(require("path"), 1);
35
35
  var import_test = require("@playwright/test");
36
36
  var import_global_setup = require("../global-setup/index.js");
37
37
  var import_monocartCoverage = require("../monocartCoverage/index.js");
38
- const DEFAULT_ACTION_TIMEOUT = 3e4;
39
- const DEFAULT_NAVIGATION_TIMEOUT = 45e3;
38
+ const DEFAULT_ACTION_TIMEOUT = 6e4;
39
+ const DEFAULT_NAVIGATION_TIMEOUT = 6e4;
40
40
  const DEFAULT_TEST_TIMEOUT = 12e4;
41
- const DEFAULT_EXPECT_TIMEOUT = 3e4;
41
+ const DEFAULT_EXPECT_TIMEOUT = 6e4;
42
42
  const FAST_MODE_USE = {
43
43
  trace: "off",
44
44
  screenshot: "off",
@@ -52,7 +52,7 @@ const DEFAULT_USE = {
52
52
  const CI_CONFIG = {
53
53
  workers: "100%",
54
54
  forbidOnly: true,
55
- retries: 2,
55
+ retries: 3,
56
56
  reporter: [
57
57
  ["list"],
58
58
  ["junit", { outputFile: "playwright-report/junit.xml" }]
@@ -61,7 +61,7 @@ const CI_CONFIG = {
61
61
  const LOCAL_CONFIG = {
62
62
  workers: "50%",
63
63
  forbidOnly: false,
64
- retries: 0,
64
+ retries: 2,
65
65
  reporter: [
66
66
  ["html", { outputFolder: "playwright-report" }],
67
67
  ["list"]
@@ -0,0 +1,231 @@
1
+ import { test, expect } from "@playwright/test";
2
+ import { AuthManager } from "../auth/index.js";
3
+ import { PageSetup } from "../page-setup/index.js";
4
+ import {
5
+ startCoverage,
6
+ stopCoverage,
7
+ trackPage,
8
+ untrackPage
9
+ } from "../monocartCoverage/index.js";
10
+ const DEFAULT_NAVIGATION_TIMEOUT = 6e4;
11
+ const DEFAULT_ELEMENT_TIMEOUT = 5e3;
12
+ class BaseTest {
13
+ auth = new AuthManager();
14
+ pageSetup = new PageSetup();
15
+ /** Whether sessionStorage was injected via `addInitScript`. */
16
+ sessionInjectedViaInitScript = false;
17
+ /** Top-level Playwright page. Used for navigation, auth, and interaction. */
18
+ page;
19
+ /**
20
+ * Alias for {@link page}. Available after calling a navigation
21
+ * method such as {@link goToEmAdminUI}. Pass to page objects
22
+ * via a callback: `() => this.appFrame`.
23
+ */
24
+ appFrame;
25
+ // ─── Credentials ─────────────────────────────────────────────────────────────
26
+ /**
27
+ * Return the credentials used for the encw login flow.
28
+ *
29
+ * Reads from environment variables with local-development defaults:
30
+ *
31
+ * | Variable | Default |
32
+ * |---------------------|---------------|
33
+ * | `ENCW_INSTANCE_ID` | `BE11226875` |
34
+ * | `ENCW_USER_ID` | `admin` |
35
+ * | `ENCW_PASSWORD` | `Password#!23` |
36
+ *
37
+ * Override this method to supply different credentials.
38
+ */
39
+ getCredentials() {
40
+ return {
41
+ instanceId: process.env.ENCW_INSTANCE_ID ?? "BE11226875",
42
+ username: process.env.ENCW_USER_ID ?? "admin",
43
+ password: process.env.ENCW_PASSWORD ?? "Password#!23"
44
+ };
45
+ }
46
+ // ─── Auth orchestration ──────────────────────────────────────────────────────
47
+ /**
48
+ * Ensure the browser has a valid encw session.
49
+ *
50
+ * - First test in a worker: performs the full login flow and
51
+ * snapshots session storage.
52
+ * - Subsequent tests: session is injected during
53
+ * {@link navigateToApp}.
54
+ *
55
+ * This method does **not** navigate to any app route.
56
+ */
57
+ async ensureAuth() {
58
+ await this.pageSetup.apply(this.page);
59
+ if (!this.auth.hasValidAuth() && AuthManager.loadFromFile()) {
60
+ const state = AuthManager.getAuthState();
61
+ if (state) {
62
+ await this.page.addInitScript((entries) => {
63
+ for (const [key, value] of Object.entries(entries)) {
64
+ sessionStorage.setItem(key, value);
65
+ }
66
+ }, state.sessionEntries);
67
+ this.sessionInjectedViaInitScript = true;
68
+ }
69
+ }
70
+ if (this.auth.hasValidAuth()) {
71
+ return;
72
+ }
73
+ await this.auth.login(this.page, this.getCredentials());
74
+ await this.auth.capture(this.page);
75
+ }
76
+ // ─── App navigation ────────────────────────────────────────────────────────
77
+ /**
78
+ * Navigate to an application route.
79
+ *
80
+ * Handles auth injection (for cached sessions) and page navigation.
81
+ * @param route - URL path to navigate to (e.g. `/admin`).
82
+ */
83
+ async navigateToApp(route) {
84
+ if (this.sessionInjectedViaInitScript) {
85
+ await this.page.goto(route, { waitUntil: "domcontentloaded" });
86
+ return;
87
+ }
88
+ if (this.auth.hasValidAuth()) {
89
+ await this.page.goto("", { waitUntil: "domcontentloaded" });
90
+ await this.auth.inject(this.page);
91
+ }
92
+ await this.page.goto(route, {
93
+ waitUntil: "domcontentloaded"
94
+ });
95
+ }
96
+ /**
97
+ * Log in to encw and navigate to the **em-admin-ui** app.
98
+ * After this method returns, {@link page} is on the admin route.
99
+ */
100
+ async goToEmAdminUI() {
101
+ await this.navigateToApp("/admin");
102
+ }
103
+ /**
104
+ * Log in to encw and navigate to the **pipeline** app.
105
+ * After this method returns, {@link page} is on the pipeline route.
106
+ */
107
+ async goToPipeline() {
108
+ await this.navigateToApp("/pipeline");
109
+ }
110
+ // ─── Navigation helpers ──────────────────────────────────────────────────────
111
+ /**
112
+ * Navigate to a URL path.
113
+ * @param path - Absolute URL path (e.g. `/admin/oneadmin/migrate`).
114
+ * @param options - Navigation options forwarded to Playwright.
115
+ */
116
+ async goto(path, options = {}) {
117
+ const {
118
+ waitUntil = "domcontentloaded",
119
+ timeout = DEFAULT_NAVIGATION_TIMEOUT
120
+ } = options;
121
+ await this.page.goto(path, { waitUntil, timeout });
122
+ }
123
+ /**
124
+ * Wait for an element to be visible on the page.
125
+ * @param selector - CSS selector.
126
+ * @param options - Timeout and expected state.
127
+ * @param options.timeout
128
+ * @param options.state
129
+ */
130
+ async waitForElement(selector, options = {}) {
131
+ const { timeout = DEFAULT_ELEMENT_TIMEOUT, state = "visible" } = options;
132
+ await this.page.locator(selector).waitFor({ timeout, state });
133
+ }
134
+ /** Playwright's `expect` — exposed for assertions inside test methods. */
135
+ get expect() {
136
+ return expect;
137
+ }
138
+ // ─── Lifecycle hooks ─────────────────────────────────────────────────────────
139
+ /**
140
+ * Called once before all tests in a describe block.
141
+ * Override in a subclass to add one-time setup logic.
142
+ * Note: `this.page` is not available in this hook.
143
+ */
144
+ async beforeAll() {
145
+ }
146
+ /**
147
+ * Called once after all tests in a describe block.
148
+ * Override in a subclass to add one-time teardown logic.
149
+ * Note: `this.page` is not available in this hook.
150
+ */
151
+ async afterAll() {
152
+ }
153
+ /**
154
+ * Called before each test. Override in a subclass to add setup
155
+ * logic (e.g. `await this.goToEmAdminUI()`).
156
+ */
157
+ async beforeEach() {
158
+ }
159
+ /** Called after each test. Override to add teardown logic. */
160
+ async afterEach() {
161
+ }
162
+ // ─── Test runner ─────────────────────────────────────────────────────────────
163
+ static toReadableTitle(methodName) {
164
+ const withoutPrefix = methodName.replace(/^test/, "");
165
+ return withoutPrefix.replace(/([A-Z])/g, " $1").toLowerCase().trim();
166
+ }
167
+ /**
168
+ * Register all `test*` methods in this class with Playwright.
169
+ *
170
+ * Call once at module level after the class definition:
171
+ * ```ts
172
+ * class MySpec extends BaseTest { ... }
173
+ * MySpec.run();
174
+ * ```
175
+ */
176
+ static run() {
177
+ const TestClass = this;
178
+ const className = TestClass.name;
179
+ const proto = TestClass.prototype;
180
+ const testMethods = Object.getOwnPropertyNames(proto).filter(
181
+ (name) => name.startsWith("test") && typeof proto[name] === "function"
182
+ );
183
+ if (testMethods.length === 0) {
184
+ console.warn(
185
+ `No test methods found in ${className}. Test methods must start with 'test'.`
186
+ );
187
+ return;
188
+ }
189
+ test.describe(className, () => {
190
+ let instance;
191
+ test.beforeAll(async () => {
192
+ startCoverage();
193
+ instance = new TestClass();
194
+ if (typeof instance.beforeAll === "function") {
195
+ await instance.beforeAll();
196
+ }
197
+ });
198
+ test.beforeEach(async ({ page }) => {
199
+ instance = new TestClass();
200
+ instance.page = page;
201
+ instance.appFrame = page;
202
+ await instance.ensureAuth();
203
+ await trackPage(page);
204
+ if (typeof instance.beforeEach === "function") {
205
+ await instance.beforeEach();
206
+ }
207
+ });
208
+ test.afterEach(async () => {
209
+ if (typeof instance.afterEach === "function") {
210
+ await instance.afterEach();
211
+ }
212
+ await untrackPage(instance.page);
213
+ });
214
+ test.afterAll(async () => {
215
+ await stopCoverage();
216
+ if (typeof instance.afterAll === "function") {
217
+ await instance.afterAll();
218
+ }
219
+ });
220
+ for (const methodName of testMethods) {
221
+ const title = TestClass.toReadableTitle(methodName);
222
+ test(title, async () => {
223
+ await instance[methodName]();
224
+ });
225
+ }
226
+ });
227
+ }
228
+ }
229
+ export {
230
+ BaseTest
231
+ };
package/dist/esm/index.js CHANGED
@@ -1,3 +1,4 @@
1
+ import { BaseTest } from "./base-test/index.js";
1
2
  import { BasePage } from "./base-page/index.js";
2
3
  import { AuthManager } from "./auth/index.js";
3
4
  import { PageSetup } from "./page-setup/index.js";
@@ -11,6 +12,7 @@ import {
11
12
  export {
12
13
  AuthManager,
13
14
  BasePage,
15
+ BaseTest,
14
16
  PageSetup,
15
17
  createBrowserStackConfig,
16
18
  createPlaywrightConfig,
@@ -8,10 +8,10 @@ import {
8
8
  buildCoverageReporters,
9
9
  configureCoverage
10
10
  } from "../monocartCoverage/index.js";
11
- const DEFAULT_ACTION_TIMEOUT = 3e4;
12
- const DEFAULT_NAVIGATION_TIMEOUT = 45e3;
11
+ const DEFAULT_ACTION_TIMEOUT = 6e4;
12
+ const DEFAULT_NAVIGATION_TIMEOUT = 6e4;
13
13
  const DEFAULT_TEST_TIMEOUT = 12e4;
14
- const DEFAULT_EXPECT_TIMEOUT = 3e4;
14
+ const DEFAULT_EXPECT_TIMEOUT = 6e4;
15
15
  const FAST_MODE_USE = {
16
16
  trace: "off",
17
17
  screenshot: "off",
@@ -25,7 +25,7 @@ const DEFAULT_USE = {
25
25
  const CI_CONFIG = {
26
26
  workers: "100%",
27
27
  forbidOnly: true,
28
- retries: 2,
28
+ retries: 3,
29
29
  reporter: [
30
30
  ["list"],
31
31
  ["junit", { outputFile: "playwright-report/junit.xml" }]
@@ -34,7 +34,7 @@ const CI_CONFIG = {
34
34
  const LOCAL_CONFIG = {
35
35
  workers: "50%",
36
36
  forbidOnly: false,
37
- retries: 0,
37
+ retries: 2,
38
38
  reporter: [
39
39
  ["html", { outputFolder: "playwright-report" }],
40
40
  ["list"]
@@ -0,0 +1,126 @@
1
+ import { Page, Expect } from '@playwright/test';
2
+ import { Credentials, GotoOptions } from '../types.js';
3
+ /**
4
+ * Base class for Playwright test specs that run against
5
+ * apps hosted inside the encw (Encompass Web) shell.
6
+ *
7
+ * **Responsibilities (delegated to focused collaborators):**
8
+ * - {@link AuthManager} — encw login + session-storage caching
9
+ * - {@link PageSetup} — init scripts, overlay suppression, route blocks
10
+ *
11
+ * **Usage pattern:**
12
+ * ```ts
13
+ * class MySpec extends BaseTest {
14
+ * async beforeEach() {
15
+ * await this.goToEmAdminUI();
16
+ * }
17
+ * async testSomething() { ... }
18
+ * }
19
+ * MySpec.run();
20
+ * ```
21
+ */
22
+ export declare class BaseTest {
23
+ private readonly auth;
24
+ private readonly pageSetup;
25
+ /** Whether sessionStorage was injected via `addInitScript`. */
26
+ private sessionInjectedViaInitScript;
27
+ /** Top-level Playwright page. Used for navigation, auth, and interaction. */
28
+ protected page: Page;
29
+ /**
30
+ * Alias for {@link page}. Available after calling a navigation
31
+ * method such as {@link goToEmAdminUI}. Pass to page objects
32
+ * via a callback: `() => this.appFrame`.
33
+ */
34
+ protected appFrame: Page;
35
+ /**
36
+ * Return the credentials used for the encw login flow.
37
+ *
38
+ * Reads from environment variables with local-development defaults:
39
+ *
40
+ * | Variable | Default |
41
+ * |---------------------|---------------|
42
+ * | `ENCW_INSTANCE_ID` | `BE11226875` |
43
+ * | `ENCW_USER_ID` | `admin` |
44
+ * | `ENCW_PASSWORD` | `Password#!23` |
45
+ *
46
+ * Override this method to supply different credentials.
47
+ */
48
+ protected getCredentials(): Credentials;
49
+ /**
50
+ * Ensure the browser has a valid encw session.
51
+ *
52
+ * - First test in a worker: performs the full login flow and
53
+ * snapshots session storage.
54
+ * - Subsequent tests: session is injected during
55
+ * {@link navigateToApp}.
56
+ *
57
+ * This method does **not** navigate to any app route.
58
+ */
59
+ ensureAuth(): Promise<void>;
60
+ /**
61
+ * Navigate to an application route.
62
+ *
63
+ * Handles auth injection (for cached sessions) and page navigation.
64
+ * @param route - URL path to navigate to (e.g. `/admin`).
65
+ */
66
+ protected navigateToApp(route: string): Promise<void>;
67
+ /**
68
+ * Log in to encw and navigate to the **em-admin-ui** app.
69
+ * After this method returns, {@link page} is on the admin route.
70
+ */
71
+ protected goToEmAdminUI(): Promise<void>;
72
+ /**
73
+ * Log in to encw and navigate to the **pipeline** app.
74
+ * After this method returns, {@link page} is on the pipeline route.
75
+ */
76
+ protected goToPipeline(): Promise<void>;
77
+ /**
78
+ * Navigate to a URL path.
79
+ * @param path - Absolute URL path (e.g. `/admin/oneadmin/migrate`).
80
+ * @param options - Navigation options forwarded to Playwright.
81
+ */
82
+ protected goto(path: string, options?: GotoOptions): Promise<void>;
83
+ /**
84
+ * Wait for an element to be visible on the page.
85
+ * @param selector - CSS selector.
86
+ * @param options - Timeout and expected state.
87
+ * @param options.timeout
88
+ * @param options.state
89
+ */
90
+ protected waitForElement(selector: string, options?: {
91
+ timeout?: number;
92
+ state?: 'visible' | 'attached' | 'hidden';
93
+ }): Promise<void>;
94
+ /** Playwright's `expect` — exposed for assertions inside test methods. */
95
+ protected get expect(): Expect;
96
+ /**
97
+ * Called once before all tests in a describe block.
98
+ * Override in a subclass to add one-time setup logic.
99
+ * Note: `this.page` is not available in this hook.
100
+ */
101
+ beforeAll(): Promise<void>;
102
+ /**
103
+ * Called once after all tests in a describe block.
104
+ * Override in a subclass to add one-time teardown logic.
105
+ * Note: `this.page` is not available in this hook.
106
+ */
107
+ afterAll(): Promise<void>;
108
+ /**
109
+ * Called before each test. Override in a subclass to add setup
110
+ * logic (e.g. `await this.goToEmAdminUI()`).
111
+ */
112
+ beforeEach(): Promise<void>;
113
+ /** Called after each test. Override to add teardown logic. */
114
+ afterEach(): Promise<void>;
115
+ private static toReadableTitle;
116
+ /**
117
+ * Register all `test*` methods in this class with Playwright.
118
+ *
119
+ * Call once at module level after the class definition:
120
+ * ```ts
121
+ * class MySpec extends BaseTest { ... }
122
+ * MySpec.run();
123
+ * ```
124
+ */
125
+ static run(): void;
126
+ }