@lowdefy/e2e-utils 0.0.0-experimental-20260720072521 → 0.0.0-experimental-20260720135014

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/dist/config.js CHANGED
@@ -94,7 +94,10 @@ function createMultiAppConfig({ apps = [], commandPrefix = '', testDir = 'e2e',
94
94
  url: `http://localhost:${app.port}/api/auth/session`,
95
95
  reuseExistingServer: true,
96
96
  timeout,
97
- cwd: app.appDir
97
+ cwd: app.appDir,
98
+ env: {
99
+ NEXT_PUBLIC_LOWDEFY_E2E: 'true'
100
+ }
98
101
  };
99
102
  });
100
103
  return defineConfig({
package/dist/core/api.js CHANGED
@@ -12,7 +12,8 @@
12
12
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
13
  See the License for the specific language governing permissions and
14
14
  limitations under the License.
15
- */ async function getApiState(page, endpointId) {
15
+ */ import { expect } from '@playwright/test';
16
+ async function getApiState(page, endpointId) {
16
17
  return page.evaluate((id)=>{
17
18
  const lowdefy = window.lowdefy;
18
19
  return lowdefy?.apiResponses?.[id]?.[0];
@@ -22,4 +23,30 @@ async function getApiResponse(page, { endpointId }) {
22
23
  const state = await getApiState(page, endpointId);
23
24
  return state?.response;
24
25
  }
25
- export { getApiState, getApiResponse };
26
+ async function expectApi(page, { endpointId, loading, response, payload, timeout = 30000 }) {
27
+ if (loading !== undefined) {
28
+ await expect.poll(async ()=>{
29
+ const state = await getApiState(page, endpointId);
30
+ return state?.loading;
31
+ }, {
32
+ timeout
33
+ }).toBe(loading);
34
+ }
35
+ if (response !== undefined) {
36
+ await expect.poll(async ()=>{
37
+ const state = await getApiState(page, endpointId);
38
+ return state?.response;
39
+ }, {
40
+ timeout
41
+ }).toEqual(expect.objectContaining(response));
42
+ }
43
+ if (payload !== undefined) {
44
+ await expect.poll(async ()=>{
45
+ const state = await getApiState(page, endpointId);
46
+ return state?.payload;
47
+ }, {
48
+ timeout
49
+ }).toEqual(expect.objectContaining(payload));
50
+ }
51
+ }
52
+ export { getApiState, getApiResponse, expectApi };
@@ -13,8 +13,8 @@
13
13
  See the License for the specific language governing permissions and
14
14
  limitations under the License.
15
15
  */ export { getBlock } from './locators.js';
16
- export { goto, waitForReady, waitForPage } from './navigation.js';
17
- export { getRequestState, getRequestResponse } from './requests.js';
18
- export { getState, getBlockState, setState } from './state.js';
19
- export { getValidation } from './validation.js';
20
- export { setUrlQuery } from './url.js';
16
+ export { goto, waitForReady, expectNavigation, waitForPage } from './navigation.js';
17
+ export { getRequestState, getRequestResponse, expectRequest } from './requests.js';
18
+ export { getState, getBlockState, setState, expectState } from './state.js';
19
+ export { getValidation, expectValidationError, expectValidationWarning, expectValidationSuccess } from './validation.js';
20
+ export { expectUrl, expectUrlQuery, setUrlQuery } from './url.js';
@@ -12,7 +12,8 @@
12
12
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
13
  See the License for the specific language governing permissions and
14
14
  limitations under the License.
15
- */ async function waitForReady(page) {
15
+ */ import { expect } from '@playwright/test';
16
+ async function waitForReady(page) {
16
17
  // Wait for Lowdefy client to initialize (context exists)
17
18
  // Context key is "page:{pageId}" not just pageId
18
19
  await page.waitForFunction(()=>{
@@ -31,10 +32,13 @@ async function goto(page, path) {
31
32
  });
32
33
  await waitForReady(page);
33
34
  }
35
+ async function expectNavigation(page, urlPattern) {
36
+ await expect(page).toHaveURL(urlPattern);
37
+ }
34
38
  async function waitForPage(page, path) {
35
39
  await page.waitForURL(path, {
36
40
  waitUntil: 'domcontentloaded'
37
41
  });
38
42
  await waitForReady(page);
39
43
  }
40
- export { goto, waitForReady, waitForPage };
44
+ export { goto, waitForReady, expectNavigation, waitForPage };
@@ -12,7 +12,8 @@
12
12
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
13
  See the License for the specific language governing permissions and
14
14
  limitations under the License.
15
- */ async function getRequestState(page, requestId) {
15
+ */ import { expect } from '@playwright/test';
16
+ async function getRequestState(page, requestId) {
16
17
  return page.evaluate((reqId)=>{
17
18
  const lowdefy = window.lowdefy;
18
19
  const pageId = lowdefy?.pageId;
@@ -24,4 +25,32 @@ async function getRequestResponse(page, { requestId }) {
24
25
  const state = await getRequestState(page, requestId);
25
26
  return state?.response;
26
27
  }
27
- export { getRequestState, getRequestResponse };
28
+ async function expectRequest(page, { requestId, loading, response, payload, timeout = 30000 }) {
29
+ if (loading !== undefined) {
30
+ await expect.poll(async ()=>{
31
+ const state = await getRequestState(page, requestId);
32
+ return state?.loading;
33
+ }, {
34
+ timeout
35
+ }).toBe(loading);
36
+ }
37
+ if (response !== undefined) {
38
+ await expect.poll(async ()=>{
39
+ const state = await getRequestState(page, requestId);
40
+ return state?.response;
41
+ }, {
42
+ timeout
43
+ }).toEqual(expect.objectContaining(response));
44
+ }
45
+ // Payload is stored in the request state by the Lowdefy engine.
46
+ // It's the evaluated payload from the request config (client-side).
47
+ if (payload !== undefined) {
48
+ await expect.poll(async ()=>{
49
+ const state = await getRequestState(page, requestId);
50
+ return state?.payload;
51
+ }, {
52
+ timeout
53
+ }).toEqual(expect.objectContaining(payload));
54
+ }
55
+ }
56
+ export { getRequestState, getRequestResponse, expectRequest };
@@ -12,7 +12,9 @@
12
12
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
13
  See the License for the specific language governing permissions and
14
14
  limitations under the License.
15
- */ async function getState(page) {
15
+ */ import { expect } from '@playwright/test';
16
+ import { get } from '@lowdefy/helpers';
17
+ async function getState(page) {
16
18
  return page.evaluate(()=>{
17
19
  const lowdefy = window.lowdefy;
18
20
  const pageId = lowdefy?.pageId;
@@ -24,18 +26,26 @@ async function getBlockState(page, { blockId }) {
24
26
  return state?.[blockId];
25
27
  }
26
28
  async function setState(page, { key, value }) {
27
- // context.methods.setState does not exist on engine contexts - the engine's
28
- // action layer (see createSetState.js) writes state via State.set() and then
29
- // triggers a re-render via context._internal.update().
30
29
  await page.evaluate(({ k, v })=>{
31
30
  const lowdefy = window.lowdefy;
32
31
  const pageId = lowdefy?.pageId;
33
32
  const context = lowdefy?.contexts?.[`page:${pageId}`];
34
- context._internal.State.set(k, v);
35
- context._internal.update();
33
+ if (context?.methods?.setState) {
34
+ context.methods.setState({
35
+ [k]: v
36
+ });
37
+ }
36
38
  }, {
37
39
  k: key,
38
40
  v: value
39
41
  });
40
42
  }
41
- export { getState, getBlockState, setState };
43
+ async function expectState(page, { key, value, timeout = 5000 }) {
44
+ await expect.poll(async ()=>{
45
+ const state = await getState(page);
46
+ return get(state, key);
47
+ }, {
48
+ timeout
49
+ }).toEqual(value);
50
+ }
51
+ export { getState, getBlockState, setState, expectState };
package/dist/core/url.js CHANGED
@@ -12,7 +12,24 @@
12
12
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
13
  See the License for the specific language governing permissions and
14
14
  limitations under the License.
15
- */ async function setUrlQuery(page, { key, value }) {
15
+ */ import { expect } from '@playwright/test';
16
+ async function expectUrl(page, { url, timeout = 5000 }) {
17
+ if (!url) {
18
+ throw new Error('expectUrl requires a "url" parameter (string or RegExp).');
19
+ }
20
+ await expect(page).toHaveURL(url, {
21
+ timeout
22
+ });
23
+ }
24
+ async function expectUrlQuery(page, { key, value, timeout = 5000 }) {
25
+ await expect.poll(async ()=>{
26
+ const url = new URL(page.url());
27
+ return url.searchParams.get(key);
28
+ }, {
29
+ timeout
30
+ }).toBe(value);
31
+ }
32
+ async function setUrlQuery(page, { key, value }) {
16
33
  await page.evaluate(({ k, v })=>{
17
34
  const url = new URL(window.location.href);
18
35
  if (v === null || v === undefined) {
@@ -26,4 +43,4 @@
26
43
  v: value
27
44
  });
28
45
  }
29
- export { setUrlQuery };
46
+ export { expectUrl, expectUrlQuery, setUrlQuery };
@@ -12,7 +12,8 @@
12
12
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
13
  See the License for the specific language governing permissions and
14
14
  limitations under the License.
15
- */ async function getValidation(page, blockId) {
15
+ */ import { expect } from '@playwright/test';
16
+ async function getValidation(page, blockId) {
16
17
  return page.evaluate((id)=>{
17
18
  const lowdefy = window.lowdefy;
18
19
  const pageId = lowdefy?.pageId;
@@ -21,4 +22,51 @@
21
22
  return block?.validationEval?.output;
22
23
  }, blockId);
23
24
  }
24
- export { getValidation };
25
+ async function expectValidationStatus(page, { blockId, status, timeout = 5000 }) {
26
+ await expect.poll(async ()=>{
27
+ const validation = await getValidation(page, blockId);
28
+ return validation?.status;
29
+ }, {
30
+ timeout
31
+ }).toBe(status);
32
+ }
33
+ async function expectValidationError(page, { blockId, message, timeout = 5000 }) {
34
+ await expect.poll(async ()=>{
35
+ const validation = await getValidation(page, blockId);
36
+ if (validation?.status !== 'error') return {
37
+ status: validation?.status
38
+ };
39
+ if (message && !validation?.errors?.includes(message)) {
40
+ return {
41
+ errors: validation?.errors
42
+ };
43
+ }
44
+ return true;
45
+ }, {
46
+ timeout
47
+ }).toBe(true);
48
+ }
49
+ async function expectValidationWarning(page, { blockId, message, timeout = 5000 }) {
50
+ await expect.poll(async ()=>{
51
+ const validation = await getValidation(page, blockId);
52
+ if (validation?.status !== 'warning') return {
53
+ status: validation?.status
54
+ };
55
+ if (message && !validation?.warnings?.includes(message)) {
56
+ return {
57
+ warnings: validation?.warnings
58
+ };
59
+ }
60
+ return true;
61
+ }, {
62
+ timeout
63
+ }).toBe(true);
64
+ }
65
+ async function expectValidationSuccess(page, { blockId, timeout = 5000 }) {
66
+ await expectValidationStatus(page, {
67
+ blockId,
68
+ status: 'success',
69
+ timeout
70
+ });
71
+ }
72
+ export { getValidation, expectValidationStatus, expectValidationError, expectValidationWarning, expectValidationSuccess };
@@ -20,20 +20,6 @@ import createPageManager from '../proxy/createPageManager.js';
20
20
  import { generateManifest, loadManifest } from '../testPrep/generateManifest.js';
21
21
  import { createMockManager, loadStaticMocks } from '../mocking/index.js';
22
22
  import { setUserCookie } from '../core/userCookie.js';
23
- import { expectState } from '../assertions/state.js';
24
- import { expectRequest } from '../assertions/requests.js';
25
- import { expectApi } from '../assertions/api.js';
26
- import { expectUrl, expectUrlQuery } from '../assertions/url.js';
27
- // The Playwright `expect` implementations createPageManager needs for its
28
- // `.expect.*` methods - injected here so createPageManager itself (exported from
29
- // the "./runtime" subpath too) never has to import @playwright/test.
30
- const assertions = {
31
- expectState,
32
- expectRequest,
33
- expectApi,
34
- expectUrl,
35
- expectUrlQuery
36
- };
37
23
  const DEFAULT_BUILD_DIR = '.lowdefy/server/build';
38
24
  // Create test with ldf fixture
39
25
  export const test = base.extend({
@@ -163,8 +149,7 @@ export const test = base.extend({
163
149
  page,
164
150
  manifest,
165
151
  helperRegistry,
166
- mockManager,
167
- assertions
152
+ mockManager
168
153
  });
169
154
  await use(pageManager);
170
155
  await mockManager.cleanup();
package/dist/index.js CHANGED
@@ -12,32 +12,21 @@
12
12
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
13
  See the License for the specific language governing permissions and
14
14
  limitations under the License.
15
- */ // Core helpers (runner-agnostic - also available from the "./runtime" subpath)
15
+ */ // Core helpers
16
16
  import { escapeId } from './core/escapeId.js';
17
17
  import { getBlock } from './core/locators.js';
18
- import { goto, waitForReady, waitForPage } from './core/navigation.js';
19
- import { getRequestState, getRequestResponse } from './core/requests.js';
20
- import { getState, getBlockState, setState } from './core/state.js';
21
- import { getValidation } from './core/validation.js';
22
- import { setUrlQuery } from './core/url.js';
18
+ import { goto, waitForReady, expectNavigation, waitForPage } from './core/navigation.js';
19
+ import { getRequestState, getRequestResponse, expectRequest } from './core/requests.js';
20
+ import { getState, getBlockState, setState, expectState } from './core/state.js';
21
+ import { getValidation, expectValidationStatus, expectValidationError, expectValidationWarning, expectValidationSuccess } from './core/validation.js';
22
+ import { expectUrl, expectUrlQuery, setUrlQuery } from './core/url.js';
23
23
  export { escapeId };
24
24
  export { getBlock };
25
- export { goto, waitForReady, waitForPage };
26
- export { getRequestState, getRequestResponse };
27
- export { getState, getBlockState, setState };
28
- export { getValidation };
29
- export { setUrlQuery };
30
- // Assertions (coupled to @playwright/test)
31
- import { expectNavigation } from './assertions/navigation.js';
32
- import { expectRequest } from './assertions/requests.js';
33
- import { expectState } from './assertions/state.js';
34
- import { expectValidationStatus, expectValidationError, expectValidationWarning, expectValidationSuccess } from './assertions/validation.js';
35
- import { expectUrl, expectUrlQuery } from './assertions/url.js';
36
- export { expectNavigation };
37
- export { expectRequest };
38
- export { expectState };
39
- export { expectValidationStatus, expectValidationError, expectValidationWarning, expectValidationSuccess };
40
- export { expectUrl, expectUrlQuery };
25
+ export { goto, waitForReady, expectNavigation, waitForPage };
26
+ export { getRequestState, getRequestResponse, expectRequest };
27
+ export { getState, getBlockState, setState, expectState };
28
+ export { getValidation, expectValidationStatus, expectValidationError, expectValidationWarning, expectValidationSuccess };
29
+ export { expectUrl, expectUrlQuery, setUrlQuery };
41
30
  // Test prep utilities
42
31
  import { generateManifest, loadManifest } from './testPrep/generateManifest.js';
43
32
  export { generateManifest, loadManifest };
@@ -13,7 +13,7 @@
13
13
  See the License for the specific language governing permissions and
14
14
  limitations under the License.
15
15
  */ import { expect } from '@playwright/test';
16
- import { expectValidationError, expectValidationWarning, expectValidationSuccess } from '../assertions/validation.js';
16
+ import { expectValidationError, expectValidationWarning, expectValidationSuccess } from '../core/validation.js';
17
17
  // Each block's e2e helper defines a `locator` function that targets the block element on the page.
18
18
  // Two locator patterns exist:
19
19
  // - `#${escapeId(blockId)}` — for blocks that render `id={blockId}` on their root DOM element
@@ -14,26 +14,16 @@
14
14
  limitations under the License.
15
15
  */ import { getBlock } from '../core/locators.js';
16
16
  import { waitForReady, waitForPage } from '../core/navigation.js';
17
- import { getState, getBlockState, setState } from '../core/state.js';
18
- import { getRequestState, getRequestResponse } from '../core/requests.js';
19
- import { getApiState, getApiResponse } from '../core/api.js';
17
+ import { getState, getBlockState, setState, expectState } from '../core/state.js';
18
+ import { getRequestState, getRequestResponse, expectRequest } from '../core/requests.js';
19
+ import { getApiState, getApiResponse, expectApi } from '../core/api.js';
20
20
  import { getValidation } from '../core/validation.js';
21
- import { setUrlQuery } from '../core/url.js';
21
+ import { expectUrl, expectUrlQuery, setUrlQuery } from '../core/url.js';
22
22
  import { setUserCookie, clearUserCookie } from '../core/userCookie.js';
23
23
  import { get, type } from '@lowdefy/helpers';
24
24
  import createBlockMethodProxy from './createBlockMethodProxy.js';
25
25
  import resolveTemplateId from './resolveTemplateId.js';
26
- // createPageManager itself stays free of @playwright/test (it is exported from the
27
- // "./runtime" subpath). The Playwright-backed `expect*` functions are injected via
28
- // `assertions` by the caller - the "./fixtures" ldf fixture wires these automatically.
29
- function requireAssertion(fn, name) {
30
- if (type.isUndefined(fn)) {
31
- throw new Error(`createPageManager: "${name}" assertion is not available on this instance. ` + `Import { ${name} } from "@lowdefy/e2e-utils" and pass it as assertions.${name}, ` + `or use the "@lowdefy/e2e-utils/fixtures" ldf fixture, which wires assertions automatically.`);
32
- }
33
- return fn;
34
- }
35
- function createPageManager({ page, manifest, helperRegistry, mockManager, assertions = {} }) {
36
- const { expectState, expectRequest, expectApi, expectUrl, expectUrlQuery } = assertions;
26
+ function createPageManager({ page, manifest, helperRegistry, mockManager }) {
37
27
  let currentBlockMap = null;
38
28
  let currentPageId = null;
39
29
  function ensurePageLoaded() {
@@ -152,17 +142,17 @@ function createPageManager({ page, manifest, helperRegistry, mockManager, assert
152
142
  request (requestId) {
153
143
  return {
154
144
  expect: {
155
- toFinish: (opts)=>requireAssertion(expectRequest, 'expectRequest')(page, {
145
+ toFinish: (opts)=>expectRequest(page, {
156
146
  requestId,
157
147
  loading: false,
158
148
  ...opts
159
149
  }),
160
- toHaveResponse: (response, opts)=>requireAssertion(expectRequest, 'expectRequest')(page, {
150
+ toHaveResponse: (response, opts)=>expectRequest(page, {
161
151
  requestId,
162
152
  response,
163
153
  ...opts
164
154
  }),
165
- toHavePayload: (payload, opts)=>requireAssertion(expectRequest, 'expectRequest')(page, {
155
+ toHavePayload: (payload, opts)=>expectRequest(page, {
166
156
  requestId,
167
157
  payload,
168
158
  ...opts
@@ -178,17 +168,17 @@ function createPageManager({ page, manifest, helperRegistry, mockManager, assert
178
168
  api (endpointId) {
179
169
  return {
180
170
  expect: {
181
- toFinish: (opts)=>requireAssertion(expectApi, 'expectApi')(page, {
171
+ toFinish: (opts)=>expectApi(page, {
182
172
  endpointId,
183
173
  loading: false,
184
174
  ...opts
185
175
  }),
186
- toHaveResponse: (response, opts)=>requireAssertion(expectApi, 'expectApi')(page, {
176
+ toHaveResponse: (response, opts)=>expectApi(page, {
187
177
  endpointId,
188
178
  response,
189
179
  ...opts
190
180
  }),
191
- toHavePayload: (payload, opts)=>requireAssertion(expectApi, 'expectApi')(page, {
181
+ toHavePayload: (payload, opts)=>expectApi(page, {
192
182
  endpointId,
193
183
  payload,
194
184
  ...opts
@@ -215,7 +205,7 @@ function createPageManager({ page, manifest, helperRegistry, mockManager, assert
215
205
  })
216
206
  },
217
207
  expect: {
218
- toBe: (value, opts)=>requireAssertion(expectState, 'expectState')(page, {
208
+ toBe: (value, opts)=>expectState(page, {
219
209
  key,
220
210
  value,
221
211
  ...opts
@@ -228,11 +218,11 @@ function createPageManager({ page, manifest, helperRegistry, mockManager, assert
228
218
  url () {
229
219
  return {
230
220
  expect: {
231
- toBe: (path, opts)=>requireAssertion(expectUrl, 'expectUrl')(page, {
221
+ toBe: (path, opts)=>expectUrl(page, {
232
222
  url: path,
233
223
  ...opts
234
224
  }),
235
- toMatch: (pattern, opts)=>requireAssertion(expectUrl, 'expectUrl')(page, {
225
+ toMatch: (pattern, opts)=>expectUrl(page, {
236
226
  url: pattern,
237
227
  ...opts
238
228
  })
@@ -250,7 +240,7 @@ function createPageManager({ page, manifest, helperRegistry, mockManager, assert
250
240
  })
251
241
  },
252
242
  expect: {
253
- toBe: (value, opts)=>requireAssertion(expectUrlQuery, 'expectUrlQuery')(page, {
243
+ toBe: (value, opts)=>expectUrlQuery(page, {
254
244
  key,
255
245
  value,
256
246
  ...opts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lowdefy/e2e-utils",
3
- "version": "0.0.0-experimental-20260720072521",
3
+ "version": "0.0.0-experimental-20260720135014",
4
4
  "license": "Apache-2.0",
5
5
  "description": "Lowdefy E2E Testing Utilities for Playwright",
6
6
  "homepage": "https://lowdefy.com",
@@ -30,23 +30,22 @@
30
30
  "exports": {
31
31
  ".": "./dist/index.js",
32
32
  "./config": "./dist/config.js",
33
- "./fixtures": "./dist/fixtures/index.js",
34
- "./runtime": "./dist/runtime.js"
33
+ "./fixtures": "./dist/fixtures/index.js"
35
34
  },
36
35
  "files": [
37
36
  "dist/*"
38
37
  ],
39
38
  "dependencies": {
40
- "@lowdefy/helpers": "0.0.0-experimental-20260720072521",
39
+ "@lowdefy/helpers": "0.0.0-experimental-20260720135014",
41
40
  "js-yaml": "4.1.0",
42
41
  "prompts": "2.4.2"
43
42
  },
44
43
  "peerDependencies": {
45
- "@playwright/test": "1.59.1"
44
+ "@playwright/test": "1.50.1"
46
45
  },
47
46
  "devDependencies": {
48
- "@swc/cli": "0.8.1",
49
- "@swc/core": "1.15.32",
47
+ "@swc/cli": "0.8.0",
48
+ "@swc/core": "1.15.18",
50
49
  "copyfiles": "2.4.1",
51
50
  "jest": "28.1.3"
52
51
  },
@@ -1,43 +0,0 @@
1
- /*
2
- Copyright 2020-2026 Lowdefy, Inc
3
-
4
- Licensed under the Apache License, Version 2.0 (the "License");
5
- you may not use this file except in compliance with the License.
6
- You may obtain a copy of the License at
7
-
8
- http://www.apache.org/licenses/LICENSE-2.0
9
-
10
- Unless required by applicable law or agreed to in writing, software
11
- distributed under the License is distributed on an "AS IS" BASIS,
12
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
- See the License for the specific language governing permissions and
14
- limitations under the License.
15
- */ import { expect } from '@playwright/test';
16
- import { getApiState } from '../core/api.js';
17
- async function expectApi(page, { endpointId, loading, response, payload, timeout = 30000 }) {
18
- if (loading !== undefined) {
19
- await expect.poll(async ()=>{
20
- const state = await getApiState(page, endpointId);
21
- return state?.loading;
22
- }, {
23
- timeout
24
- }).toBe(loading);
25
- }
26
- if (response !== undefined) {
27
- await expect.poll(async ()=>{
28
- const state = await getApiState(page, endpointId);
29
- return state?.response;
30
- }, {
31
- timeout
32
- }).toEqual(expect.objectContaining(response));
33
- }
34
- if (payload !== undefined) {
35
- await expect.poll(async ()=>{
36
- const state = await getApiState(page, endpointId);
37
- return state?.payload;
38
- }, {
39
- timeout
40
- }).toEqual(expect.objectContaining(payload));
41
- }
42
- }
43
- export { expectApi };
@@ -1,20 +0,0 @@
1
- /*
2
- Copyright 2020-2026 Lowdefy, Inc
3
-
4
- Licensed under the Apache License, Version 2.0 (the "License");
5
- you may not use this file except in compliance with the License.
6
- You may obtain a copy of the License at
7
-
8
- http://www.apache.org/licenses/LICENSE-2.0
9
-
10
- Unless required by applicable law or agreed to in writing, software
11
- distributed under the License is distributed on an "AS IS" BASIS,
12
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
- See the License for the specific language governing permissions and
14
- limitations under the License.
15
- */ export { expectState } from './state.js';
16
- export { expectRequest } from './requests.js';
17
- export { expectApi } from './api.js';
18
- export { expectNavigation } from './navigation.js';
19
- export { expectUrl, expectUrlQuery } from './url.js';
20
- export { expectValidationStatus, expectValidationError, expectValidationWarning, expectValidationSuccess } from './validation.js';
@@ -1,19 +0,0 @@
1
- /*
2
- Copyright 2020-2026 Lowdefy, Inc
3
-
4
- Licensed under the Apache License, Version 2.0 (the "License");
5
- you may not use this file except in compliance with the License.
6
- You may obtain a copy of the License at
7
-
8
- http://www.apache.org/licenses/LICENSE-2.0
9
-
10
- Unless required by applicable law or agreed to in writing, software
11
- distributed under the License is distributed on an "AS IS" BASIS,
12
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
- See the License for the specific language governing permissions and
14
- limitations under the License.
15
- */ import { expect } from '@playwright/test';
16
- async function expectNavigation(page, urlPattern) {
17
- await expect(page).toHaveURL(urlPattern);
18
- }
19
- export { expectNavigation };
@@ -1,45 +0,0 @@
1
- /*
2
- Copyright 2020-2026 Lowdefy, Inc
3
-
4
- Licensed under the Apache License, Version 2.0 (the "License");
5
- you may not use this file except in compliance with the License.
6
- You may obtain a copy of the License at
7
-
8
- http://www.apache.org/licenses/LICENSE-2.0
9
-
10
- Unless required by applicable law or agreed to in writing, software
11
- distributed under the License is distributed on an "AS IS" BASIS,
12
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
- See the License for the specific language governing permissions and
14
- limitations under the License.
15
- */ import { expect } from '@playwright/test';
16
- import { getRequestState } from '../core/requests.js';
17
- async function expectRequest(page, { requestId, loading, response, payload, timeout = 30000 }) {
18
- if (loading !== undefined) {
19
- await expect.poll(async ()=>{
20
- const state = await getRequestState(page, requestId);
21
- return state?.loading;
22
- }, {
23
- timeout
24
- }).toBe(loading);
25
- }
26
- if (response !== undefined) {
27
- await expect.poll(async ()=>{
28
- const state = await getRequestState(page, requestId);
29
- return state?.response;
30
- }, {
31
- timeout
32
- }).toEqual(expect.objectContaining(response));
33
- }
34
- // Payload is stored in the request state by the Lowdefy engine.
35
- // It's the evaluated payload from the request config (client-side).
36
- if (payload !== undefined) {
37
- await expect.poll(async ()=>{
38
- const state = await getRequestState(page, requestId);
39
- return state?.payload;
40
- }, {
41
- timeout
42
- }).toEqual(expect.objectContaining(payload));
43
- }
44
- }
45
- export { expectRequest };
@@ -1,26 +0,0 @@
1
- /*
2
- Copyright 2020-2026 Lowdefy, Inc
3
-
4
- Licensed under the Apache License, Version 2.0 (the "License");
5
- you may not use this file except in compliance with the License.
6
- You may obtain a copy of the License at
7
-
8
- http://www.apache.org/licenses/LICENSE-2.0
9
-
10
- Unless required by applicable law or agreed to in writing, software
11
- distributed under the License is distributed on an "AS IS" BASIS,
12
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
- See the License for the specific language governing permissions and
14
- limitations under the License.
15
- */ import { expect } from '@playwright/test';
16
- import { get } from '@lowdefy/helpers';
17
- import { getState } from '../core/state.js';
18
- async function expectState(page, { key, value, timeout = 5000 }) {
19
- await expect.poll(async ()=>{
20
- const state = await getState(page);
21
- return get(state, key);
22
- }, {
23
- timeout
24
- }).toEqual(value);
25
- }
26
- export { expectState };
@@ -1,32 +0,0 @@
1
- /*
2
- Copyright 2020-2026 Lowdefy, Inc
3
-
4
- Licensed under the Apache License, Version 2.0 (the "License");
5
- you may not use this file except in compliance with the License.
6
- You may obtain a copy of the License at
7
-
8
- http://www.apache.org/licenses/LICENSE-2.0
9
-
10
- Unless required by applicable law or agreed to in writing, software
11
- distributed under the License is distributed on an "AS IS" BASIS,
12
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
- See the License for the specific language governing permissions and
14
- limitations under the License.
15
- */ import { expect } from '@playwright/test';
16
- async function expectUrl(page, { url, timeout = 5000 }) {
17
- if (!url) {
18
- throw new Error('expectUrl requires a "url" parameter (string or RegExp).');
19
- }
20
- await expect(page).toHaveURL(url, {
21
- timeout
22
- });
23
- }
24
- async function expectUrlQuery(page, { key, value, timeout = 5000 }) {
25
- await expect.poll(async ()=>{
26
- const url = new URL(page.url());
27
- return url.searchParams.get(key);
28
- }, {
29
- timeout
30
- }).toBe(value);
31
- }
32
- export { expectUrl, expectUrlQuery };
@@ -1,64 +0,0 @@
1
- /*
2
- Copyright 2020-2026 Lowdefy, Inc
3
-
4
- Licensed under the Apache License, Version 2.0 (the "License");
5
- you may not use this file except in compliance with the License.
6
- You may obtain a copy of the License at
7
-
8
- http://www.apache.org/licenses/LICENSE-2.0
9
-
10
- Unless required by applicable law or agreed to in writing, software
11
- distributed under the License is distributed on an "AS IS" BASIS,
12
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
- See the License for the specific language governing permissions and
14
- limitations under the License.
15
- */ import { expect } from '@playwright/test';
16
- import { getValidation } from '../core/validation.js';
17
- async function expectValidationStatus(page, { blockId, status, timeout = 5000 }) {
18
- await expect.poll(async ()=>{
19
- const validation = await getValidation(page, blockId);
20
- return validation?.status;
21
- }, {
22
- timeout
23
- }).toBe(status);
24
- }
25
- async function expectValidationError(page, { blockId, message, timeout = 5000 }) {
26
- await expect.poll(async ()=>{
27
- const validation = await getValidation(page, blockId);
28
- if (validation?.status !== 'error') return {
29
- status: validation?.status
30
- };
31
- if (message && !validation?.errors?.includes(message)) {
32
- return {
33
- errors: validation?.errors
34
- };
35
- }
36
- return true;
37
- }, {
38
- timeout
39
- }).toBe(true);
40
- }
41
- async function expectValidationWarning(page, { blockId, message, timeout = 5000 }) {
42
- await expect.poll(async ()=>{
43
- const validation = await getValidation(page, blockId);
44
- if (validation?.status !== 'warning') return {
45
- status: validation?.status
46
- };
47
- if (message && !validation?.warnings?.includes(message)) {
48
- return {
49
- warnings: validation?.warnings
50
- };
51
- }
52
- return true;
53
- }, {
54
- timeout
55
- }).toBe(true);
56
- }
57
- async function expectValidationSuccess(page, { blockId, timeout = 5000 }) {
58
- await expectValidationStatus(page, {
59
- blockId,
60
- status: 'success',
61
- timeout
62
- });
63
- }
64
- export { expectValidationStatus, expectValidationError, expectValidationWarning, expectValidationSuccess };
package/dist/runtime.js DELETED
@@ -1,32 +0,0 @@
1
- /*
2
- Copyright 2020-2026 Lowdefy, Inc
3
-
4
- Licensed under the Apache License, Version 2.0 (the "License");
5
- you may not use this file except in compliance with the License.
6
- You may obtain a copy of the License at
7
-
8
- http://www.apache.org/licenses/LICENSE-2.0
9
-
10
- Unless required by applicable law or agreed to in writing, software
11
- distributed under the License is distributed on an "AS IS" BASIS,
12
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
- See the License for the specific language governing permissions and
14
- limitations under the License.
15
- */ // Runner-agnostic surface: reading/writing a Lowdefy Page via the Playwright
16
- // `page` interface, with no dependency on @playwright/test. Useful for driving
17
- // a page from tooling that isn't a Playwright test run (e.g. headless
18
- // inspection). The `expect*` assertion helpers live in "./assertions" and the
19
- // full test-authoring API (which does depend on @playwright/test) is exported
20
- // from "." and "./fixtures".
21
- export { escapeId } from './core/escapeId.js';
22
- export { getBlock } from './core/locators.js';
23
- export { goto, waitForReady, waitForPage } from './core/navigation.js';
24
- export { getRequestState, getRequestResponse } from './core/requests.js';
25
- export { getApiState, getApiResponse } from './core/api.js';
26
- export { getState, getBlockState, setState } from './core/state.js';
27
- export { getValidation } from './core/validation.js';
28
- export { setUrlQuery } from './core/url.js';
29
- export { setUserCookie, clearUserCookie } from './core/userCookie.js';
30
- export { generateManifest, loadManifest } from './testPrep/generateManifest.js';
31
- export { createMockManager, loadStaticMocks } from './mocking/index.js';
32
- export { default as createPageManager } from './proxy/createPageManager.js';