@testspectra/cli 1.0.69 → 1.1.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/LICENSE.md +48 -0
- package/README.md +36 -270
- package/bin/.testspectra-runner.hash +1 -0
- package/bin/spectra.js +1 -1
- package/bin/testspectra-runner +0 -0
- package/demo-app/assets/index-DPfv5_EF.js +116 -0
- package/demo-app/assets/index-gIwu2EMV.css +1 -0
- package/demo-app/index.html +2 -2
- package/dist/.tsbuildinfo +1 -0
- package/dist/commands/__tests__/cloud-run.test.d.ts +1 -0
- package/dist/commands/__tests__/cloud-run.test.js +93 -0
- package/dist/commands/__tests__/doctor.test.d.ts +1 -0
- package/dist/commands/__tests__/doctor.test.js +39 -0
- package/dist/commands/__tests__/init.test.d.ts +1 -0
- package/dist/commands/__tests__/init.test.js +148 -0
- package/dist/commands/__tests__/license.test.d.ts +1 -0
- package/dist/commands/__tests__/license.test.js +13 -0
- package/dist/commands/__tests__/refactor.test.d.ts +1 -0
- package/dist/commands/__tests__/refactor.test.js +64 -0
- package/dist/commands/__tests__/run-e2e.test.d.ts +1 -0
- package/dist/commands/__tests__/run-e2e.test.js +181 -0
- package/dist/commands/__tests__/run.test.d.ts +1 -0
- package/dist/commands/__tests__/run.test.js +197 -0
- package/dist/commands/__tests__/watch.test.d.ts +1 -0
- package/dist/commands/__tests__/watch.test.js +155 -0
- package/dist/commands/add.js +86 -85
- package/dist/commands/cloud-run.d.ts +11 -0
- package/dist/commands/cloud-run.js +118 -0
- package/dist/commands/demo.js +7 -7
- package/dist/commands/devices.d.ts +14 -2
- package/dist/commands/devices.js +44 -34
- package/dist/commands/doctor.d.ts +3 -1
- package/dist/commands/doctor.js +43 -264
- package/dist/commands/init.d.ts +1 -1
- package/dist/commands/init.js +206 -196
- package/dist/commands/install.d.ts +4 -0
- package/dist/commands/install.js +59 -0
- package/dist/commands/license.d.ts +4 -0
- package/dist/commands/license.js +30 -0
- package/dist/commands/refactor.d.ts +8 -0
- package/dist/commands/refactor.js +78 -0
- package/dist/commands/run.d.ts +22 -1
- package/dist/commands/run.js +252 -109
- package/dist/commands/sync-types.d.ts +4 -0
- package/dist/commands/sync-types.js +14 -0
- package/dist/commands/update.d.ts +3 -0
- package/dist/commands/update.js +109 -0
- package/dist/commands/watch.d.ts +6 -0
- package/dist/commands/watch.js +47 -43
- package/dist/config/loader.d.ts +1 -1
- package/dist/config/loader.js +40 -25
- package/dist/config/schema.d.ts +117 -49
- package/dist/config/schema.js +41 -34
- package/dist/generator/__tests__/tsconfig-isolation.test.d.ts +1 -0
- package/dist/generator/__tests__/tsconfig-isolation.test.js +278 -0
- package/dist/generator/__tests__/type-generator.test.d.ts +1 -0
- package/dist/generator/__tests__/type-generator.test.js +386 -0
- package/dist/generator/index.d.ts +2 -0
- package/dist/generator/index.js +2 -0
- package/dist/generator/tsconfig-generator.d.ts +27 -0
- package/dist/generator/tsconfig-generator.js +391 -0
- package/dist/generator/type-generator.d.ts +36 -0
- package/dist/generator/type-generator.js +644 -0
- package/dist/index.d.ts +9 -5
- package/dist/index.js +126 -47
- package/dist/lifecycle/__tests__/lifecycle-engine.test.d.ts +1 -0
- package/dist/lifecycle/__tests__/lifecycle-engine.test.js +290 -0
- package/dist/lifecycle/hook-discovery.d.ts +24 -0
- package/dist/lifecycle/hook-discovery.js +60 -0
- package/dist/lifecycle/hook-dispatcher.d.ts +34 -0
- package/dist/lifecycle/hook-dispatcher.js +190 -0
- package/dist/lifecycle/index.d.ts +3 -0
- package/dist/lifecycle/index.js +3 -0
- package/dist/lifecycle/parallel-grouping.d.ts +27 -0
- package/dist/lifecycle/parallel-grouping.js +151 -0
- package/dist/mobile/__tests__/android-device-e2e.test.d.ts +1 -0
- package/dist/mobile/__tests__/android-device-e2e.test.js +53 -0
- package/dist/mobile/__tests__/device-pool.test.d.ts +1 -0
- package/dist/mobile/__tests__/device-pool.test.js +97 -0
- package/dist/mobile/device-pool.d.ts +23 -0
- package/dist/mobile/device-pool.js +1 -0
- package/dist/mobile/index.d.ts +1 -0
- package/dist/mobile/index.js +1 -0
- package/dist/refactor/__tests__/refactor-engine.test.d.ts +1 -0
- package/dist/refactor/__tests__/refactor-engine.test.js +175 -0
- package/dist/refactor/index.d.ts +1 -0
- package/dist/refactor/index.js +1 -0
- package/dist/refactor/refactor-engine.d.ts +25 -0
- package/dist/refactor/refactor-engine.js +255 -0
- package/dist/reporter/__tests__/semantic-formatter.test.d.ts +1 -0
- package/dist/reporter/__tests__/semantic-formatter.test.js +73 -0
- package/dist/reporter/semantic-formatter.d.ts +6 -0
- package/dist/reporter/semantic-formatter.js +191 -0
- package/dist/reporter/summary-view.d.ts +12 -0
- package/dist/reporter/summary-view.js +19 -0
- package/dist/reporter/terminal-stream.d.ts +32 -0
- package/dist/reporter/terminal-stream.js +82 -0
- package/dist/reporter/types.d.ts +2 -0
- package/dist/reporter/types.js +1 -0
- package/dist/runner/bridge.d.ts +10 -5
- package/dist/runner/bridge.js +69 -44
- package/dist/runner/reporter.d.ts +30 -2
- package/dist/runner/reporter.js +419 -13
- package/dist/server/demo.js +43 -44
- package/dist/types/generator.d.ts +1 -17
- package/dist/types/generator.js +1 -443
- package/dist/utils/demo-server.js +38 -35
- package/package.json +20 -12
- package/templates/default/CLAUDE.md +7 -5
- package/templates/default/fixtures/apiData.json +24 -0
- package/templates/default/package.json +13 -4
- package/templates/default/page-objects/MatchersPage/mobile.ts +41 -16
- package/templates/default/page-objects/MatchersPage/web.ts +14 -0
- package/templates/default/page-objects/NavigationPage/mobile.ts +10 -1
- package/templates/default/page-objects/PlaygroundPage/mobile.ts +27 -17
- package/templates/default/page-objects/PlaygroundPage/web.ts +2 -0
- package/templates/default/specs/ApiInterception/TC-0008-fetch-mocking/mobile.test.ts +11 -0
- package/templates/default/specs/ApiInterception/TC-0008-fetch-mocking/spec.md +12 -0
- package/templates/default/specs/ApiInterception/TC-0008-fetch-mocking/web.test.ts +27 -0
- package/templates/default/specs/ApiInterception/TC-0009-post-mocking/mobile.test.ts +16 -0
- package/templates/default/specs/ApiInterception/TC-0009-post-mocking/spec.md +12 -0
- package/templates/default/specs/ApiInterception/TC-0009-post-mocking/web.test.ts +24 -0
- package/templates/default/specs/ApiInterception/suite.md +9 -0
- package/templates/default/specs/BrowserContext/TC-0007-title-and-navigation/mobile.test.ts +7 -1
- package/templates/default/specs/BrowserContext/TC-0007-title-and-navigation/web.test.ts +17 -3
- package/templates/default/specs/ContentMatchers/TC-0005-text-and-values/mobile.test.ts +15 -1
- package/templates/default/specs/ContentMatchers/TC-0005-text-and-values/web.test.ts +14 -4
- package/templates/default/specs/ContentMatchers/TC-0006-collections-and-empty/mobile.test.ts +9 -1
- package/templates/default/specs/ContentMatchers/TC-0006-collections-and-empty/web.test.ts +8 -3
- package/templates/default/specs/ElementMatchers/TC-0003-visibility-and-dom/mobile.test.ts +9 -1
- package/templates/default/specs/ElementMatchers/TC-0003-visibility-and-dom/web.test.ts +9 -3
- package/templates/default/specs/ElementMatchers/TC-0004-states-and-attributes/mobile.test.ts +27 -1
- package/templates/default/specs/ElementMatchers/TC-0004-states-and-attributes/web.test.ts +27 -6
- package/templates/default/specs/Playground/TC-0001-form-controls/mobile.test.ts +4 -1
- package/templates/default/specs/Playground/TC-0001-form-controls/web.test.ts +3 -3
- package/templates/default/specs/Playground/TC-0002-toggle-elements/mobile.test.ts +4 -1
- package/templates/default/specs/Playground/TC-0002-toggle-elements/web.test.ts +2 -2
- package/templates/default/spectra.config.ts +21 -14
- package/templates/default/support/actions/fillCredentials/mobile.action.ts +2 -2
- package/templates/default/support/steps/togglePlaygroundStates/mobile.step.ts +2 -0
- package/templates/default/support/steps/togglePlaygroundStates/web.step.ts +2 -2
- package/templates/default/support/steps/verifyPlaygroundState/mobile.step.ts +3 -1
- package/templates/default/support/steps/verifyPlaygroundState/web.step.ts +3 -3
- package/templates/default/tsconfig.json +3 -1
- package/templates/nx/.nx/workspace-data/d/daemon.log +168 -0
- package/templates/nx/CLAUDE.md +2 -2
- package/templates/nx/package.json +7 -5
- package/templates/nx/packages/matchers/e2e/specs/ApiInterception/TC-0008-fetch-mocking/mobile.test.ts +3 -0
- package/templates/nx/packages/matchers/e2e/specs/ApiInterception/TC-0008-fetch-mocking/spec.md +12 -0
- package/templates/nx/packages/matchers/e2e/specs/ApiInterception/TC-0008-fetch-mocking/web.test.ts +27 -0
- package/templates/nx/packages/matchers/e2e/specs/ApiInterception/TC-0009-post-mocking/mobile.test.ts +3 -0
- package/templates/nx/packages/matchers/e2e/specs/ApiInterception/TC-0009-post-mocking/spec.md +12 -0
- package/templates/nx/packages/matchers/e2e/specs/ApiInterception/TC-0009-post-mocking/web.test.ts +24 -0
- package/templates/nx/packages/matchers/e2e/specs/ApiInterception/suite.md +9 -0
- package/templates/nx/packages/matchers/e2e/specs/BrowserContext/TC-0007-title-and-navigation/web.test.ts +17 -3
- package/templates/nx/packages/matchers/e2e/specs/ContentMatchers/TC-0005-text-and-values/web.test.ts +14 -4
- package/templates/nx/packages/matchers/e2e/specs/ContentMatchers/TC-0006-collections-and-empty/web.test.ts +8 -3
- package/templates/nx/packages/matchers/e2e/specs/ElementMatchers/TC-0003-visibility-and-dom/web.test.ts +9 -3
- package/templates/nx/packages/matchers/e2e/specs/ElementMatchers/TC-0004-states-and-attributes/web.test.ts +27 -6
- package/templates/nx/packages/playground/e2e/specs/Playground/TC-0001-form-controls/web.test.ts +3 -3
- package/templates/nx/packages/playground/e2e/specs/Playground/TC-0002-toggle-elements/web.test.ts +2 -2
- package/templates/nx/pnpm-lock.yaml +6663 -0
- package/templates/nx/pnpm-workspace.yaml +2 -1
- package/templates/nx/shared/testing/fixtures/apiData.json +24 -0
- package/templates/nx/shared/testing/page-objects/MatchersPage/mobile.ts +12 -0
- package/templates/nx/shared/testing/page-objects/MatchersPage/web.ts +14 -0
- package/templates/nx/shared/testing/page-objects/PlaygroundPage/web.ts +2 -0
- package/templates/nx/shared/testing/project.json +19 -0
- package/templates/nx/shared/testing/support/steps/togglePlaygroundStates/web.step.ts +2 -2
- package/templates/nx/shared/testing/support/steps/verifyPlaygroundState/mobile.step.ts +1 -1
- package/templates/nx/shared/testing/support/steps/verifyPlaygroundState/web.step.ts +3 -3
- package/templates/nx/spectra.config.ts +19 -12
- package/templates/nx/tsconfig.json +3 -1
- package/demo-app/assets/index-DAUlrHTr.css +0 -1
- package/demo-app/assets/index-DN2Kb0A8.js +0 -100
- package/dist/index.cjs +0 -101
- package/dist/plugin.cjs +0 -575
- package/dist/plugin.d.ts +0 -16
- package/dist/plugin.js +0 -184
- package/dist/step/index.d.ts +0 -6
- package/dist/step/index.js +0 -6
- package/dist/step/matchers.d.ts +0 -14
- package/dist/step/matchers.js +0 -114
- package/dist/step/proto.d.ts +0 -46
- package/dist/step/proto.js +0 -114
- package/dist/step/runner/collection.d.ts +0 -13
- package/dist/step/runner/collection.js +0 -51
- package/dist/step/runner/single.d.ts +0 -21
- package/dist/step/runner/single.js +0 -138
- package/dist/step/spectra.d.ts +0 -34
- package/dist/step/spectra.js +0 -156
- package/dist/step/types.d.ts +0 -32
- package/dist/step/types.js +0 -5
- package/templates/default/tsconfig.spectra.android.json +0 -46
- package/templates/default/tsconfig.spectra.ios.json +0 -46
- package/templates/default/tsconfig.spectra.json +0 -22
- package/templates/default/tsconfig.spectra.web.json +0 -53
- package/templates/nx/fixtures/playgroundData.json +0 -7
- package/templates/nx/global-hooks/after/mobile.hook.ts +0 -3
- package/templates/nx/global-hooks/after/web.hook.ts +0 -3
- package/templates/nx/global-hooks/before/mobile.hook.ts +0 -3
- package/templates/nx/global-hooks/before/web.hook.ts +0 -3
- package/templates/nx/page-objects/MatchersPage/mobile.ts +0 -21
- package/templates/nx/page-objects/MatchersPage/web.ts +0 -23
- package/templates/nx/page-objects/NavigationPage/mobile.ts +0 -5
- package/templates/nx/page-objects/NavigationPage/web.ts +0 -8
- package/templates/nx/page-objects/PlaygroundPage/mobile.ts +0 -26
- package/templates/nx/page-objects/PlaygroundPage/web.ts +0 -29
- package/templates/nx/specs/BrowserContext/TC-0007-title-and-navigation/mobile.test.ts +0 -3
- package/templates/nx/specs/BrowserContext/TC-0007-title-and-navigation/spec.md +0 -12
- package/templates/nx/specs/BrowserContext/TC-0007-title-and-navigation/web.test.ts +0 -5
- package/templates/nx/specs/BrowserContext/suite.md +0 -9
- package/templates/nx/specs/ContentMatchers/TC-0005-text-and-values/mobile.test.ts +0 -3
- package/templates/nx/specs/ContentMatchers/TC-0005-text-and-values/spec.md +0 -12
- package/templates/nx/specs/ContentMatchers/TC-0005-text-and-values/web.test.ts +0 -7
- package/templates/nx/specs/ContentMatchers/TC-0006-collections-and-empty/mobile.test.ts +0 -3
- package/templates/nx/specs/ContentMatchers/TC-0006-collections-and-empty/spec.md +0 -12
- package/templates/nx/specs/ContentMatchers/TC-0006-collections-and-empty/web.test.ts +0 -6
- package/templates/nx/specs/ContentMatchers/suite.md +0 -9
- package/templates/nx/specs/ElementMatchers/TC-0003-visibility-and-dom/mobile.test.ts +0 -3
- package/templates/nx/specs/ElementMatchers/TC-0003-visibility-and-dom/spec.md +0 -12
- package/templates/nx/specs/ElementMatchers/TC-0003-visibility-and-dom/web.test.ts +0 -5
- package/templates/nx/specs/ElementMatchers/TC-0004-states-and-attributes/mobile.test.ts +0 -3
- package/templates/nx/specs/ElementMatchers/TC-0004-states-and-attributes/spec.md +0 -12
- package/templates/nx/specs/ElementMatchers/TC-0004-states-and-attributes/web.test.ts +0 -8
- package/templates/nx/specs/ElementMatchers/hooks/after/mobile.hook.ts +0 -1
- package/templates/nx/specs/ElementMatchers/hooks/after/web.hook.ts +0 -1
- package/templates/nx/specs/ElementMatchers/hooks/afterEach/mobile.hook.ts +0 -1
- package/templates/nx/specs/ElementMatchers/hooks/afterEach/web.hook.ts +0 -1
- package/templates/nx/specs/ElementMatchers/hooks/before/mobile.hook.ts +0 -1
- package/templates/nx/specs/ElementMatchers/hooks/before/web.hook.ts +0 -1
- package/templates/nx/specs/ElementMatchers/hooks/beforeEach/mobile.hook.ts +0 -1
- package/templates/nx/specs/ElementMatchers/hooks/beforeEach/web.hook.ts +0 -1
- package/templates/nx/specs/ElementMatchers/suite.md +0 -9
- package/templates/nx/specs/Playground/TC-0001-form-controls/mobile.test.ts +0 -3
- package/templates/nx/specs/Playground/TC-0001-form-controls/spec.md +0 -12
- package/templates/nx/specs/Playground/TC-0001-form-controls/web.test.ts +0 -6
- package/templates/nx/specs/Playground/TC-0002-toggle-elements/mobile.test.ts +0 -3
- package/templates/nx/specs/Playground/TC-0002-toggle-elements/spec.md +0 -12
- package/templates/nx/specs/Playground/TC-0002-toggle-elements/web.test.ts +0 -6
- package/templates/nx/specs/Playground/hooks/after/mobile.hook.ts +0 -1
- package/templates/nx/specs/Playground/hooks/after/web.hook.ts +0 -1
- package/templates/nx/specs/Playground/hooks/afterEach/mobile.hook.ts +0 -1
- package/templates/nx/specs/Playground/hooks/afterEach/web.hook.ts +0 -1
- package/templates/nx/specs/Playground/hooks/before/mobile.hook.ts +0 -1
- package/templates/nx/specs/Playground/hooks/before/web.hook.ts +0 -1
- package/templates/nx/specs/Playground/hooks/beforeEach/mobile.hook.ts +0 -1
- package/templates/nx/specs/Playground/hooks/beforeEach/web.hook.ts +0 -1
- package/templates/nx/specs/Playground/suite.md +0 -9
- package/templates/nx/support/actions/fillCredentials/mobile.action.ts +0 -4
- package/templates/nx/support/actions/fillCredentials/web.action.ts +0 -4
- package/templates/nx/support/steps/togglePlaygroundStates/mobile.step.ts +0 -3
- package/templates/nx/support/steps/togglePlaygroundStates/step.md +0 -7
- package/templates/nx/support/steps/togglePlaygroundStates/web.step.ts +0 -5
- package/templates/nx/support/steps/verifyPlaygroundState/mobile.step.ts +0 -4
- package/templates/nx/support/steps/verifyPlaygroundState/step.md +0 -7
- package/templates/nx/support/steps/verifyPlaygroundState/web.step.ts +0 -6
- package/templates/nx/tsconfig.spectra.android.json +0 -39
- package/templates/nx/tsconfig.spectra.ios.json +0 -39
- package/templates/nx/tsconfig.spectra.json +0 -25
- package/templates/nx/tsconfig.spectra.shared.json +0 -25
- package/templates/nx/tsconfig.spectra.web.json +0 -45
- /package/templates/{nx/specs/BrowserContext → default/specs/ApiInterception}/hooks/after/mobile.hook.ts +0 -0
- /package/templates/{nx/specs/BrowserContext → default/specs/ApiInterception}/hooks/after/web.hook.ts +0 -0
- /package/templates/{nx/specs/BrowserContext → default/specs/ApiInterception}/hooks/afterEach/mobile.hook.ts +0 -0
- /package/templates/{nx/specs/BrowserContext → default/specs/ApiInterception}/hooks/afterEach/web.hook.ts +0 -0
- /package/templates/{nx/specs/BrowserContext → default/specs/ApiInterception}/hooks/before/mobile.hook.ts +0 -0
- /package/templates/{nx/specs/BrowserContext → default/specs/ApiInterception}/hooks/before/web.hook.ts +0 -0
- /package/templates/{nx/specs/BrowserContext → default/specs/ApiInterception}/hooks/beforeEach/mobile.hook.ts +0 -0
- /package/templates/{nx/specs/BrowserContext → default/specs/ApiInterception}/hooks/beforeEach/web.hook.ts +0 -0
- /package/templates/nx/{specs/ContentMatchers → packages/matchers/e2e/specs/ApiInterception}/hooks/after/mobile.hook.ts +0 -0
- /package/templates/nx/{specs/ContentMatchers → packages/matchers/e2e/specs/ApiInterception}/hooks/after/web.hook.ts +0 -0
- /package/templates/nx/{specs/ContentMatchers → packages/matchers/e2e/specs/ApiInterception}/hooks/afterEach/mobile.hook.ts +0 -0
- /package/templates/nx/{specs/ContentMatchers → packages/matchers/e2e/specs/ApiInterception}/hooks/afterEach/web.hook.ts +0 -0
- /package/templates/nx/{specs/ContentMatchers → packages/matchers/e2e/specs/ApiInterception}/hooks/before/mobile.hook.ts +0 -0
- /package/templates/nx/{specs/ContentMatchers → packages/matchers/e2e/specs/ApiInterception}/hooks/before/web.hook.ts +0 -0
- /package/templates/nx/{specs/ContentMatchers → packages/matchers/e2e/specs/ApiInterception}/hooks/beforeEach/mobile.hook.ts +0 -0
- /package/templates/nx/{specs/ContentMatchers → packages/matchers/e2e/specs/ApiInterception}/hooks/beforeEach/web.hook.ts +0 -0
package/dist/plugin.js
DELETED
|
@@ -1,184 +0,0 @@
|
|
|
1
|
-
import fs from "fs";
|
|
2
|
-
import path from "path";
|
|
3
|
-
import { TypeGenerator } from "./types/generator.js";
|
|
4
|
-
/**
|
|
5
|
-
* Traverses upwards from `startDir` to locate the TestSpectra workspace root.
|
|
6
|
-
* Looks for indicators: `spectra.config.ts`, `.testspectra`, `pnpm-workspace.yaml`, or `nx.json`.
|
|
7
|
-
*/
|
|
8
|
-
function findWorkspaceRoot(startDir) {
|
|
9
|
-
let cur = path.resolve(startDir);
|
|
10
|
-
while (cur !== path.dirname(cur)) {
|
|
11
|
-
if (fs.existsSync(path.join(cur, "spectra.config.ts")) ||
|
|
12
|
-
fs.existsSync(path.join(cur, ".testspectra")) ||
|
|
13
|
-
fs.existsSync(path.join(cur, "pnpm-workspace.yaml")) ||
|
|
14
|
-
fs.existsSync(path.join(cur, "nx.json"))) {
|
|
15
|
-
return cur;
|
|
16
|
-
}
|
|
17
|
-
cur = path.dirname(cur);
|
|
18
|
-
}
|
|
19
|
-
return startDir;
|
|
20
|
-
}
|
|
21
|
-
function appendLog(workspaceRoot, message) {
|
|
22
|
-
try {
|
|
23
|
-
const logDir = path.join(workspaceRoot, ".testspectra", "logs");
|
|
24
|
-
if (!fs.existsSync(logDir))
|
|
25
|
-
fs.mkdirSync(logDir, { recursive: true });
|
|
26
|
-
const logFile = path.join(logDir, "plugin.log");
|
|
27
|
-
const timestamp = new Date().toISOString();
|
|
28
|
-
fs.appendFileSync(logFile, `[${timestamp}] ${message}\n`, "utf-8");
|
|
29
|
-
}
|
|
30
|
-
catch { }
|
|
31
|
-
}
|
|
32
|
-
/**
|
|
33
|
-
* TypeScript Language Service Plugin Factory for TestSpectra.
|
|
34
|
-
* Runs silently inside TSServer (VS Code, Cursor, WebStorm, Neovim, etc.).
|
|
35
|
-
*
|
|
36
|
-
* It generates and refreshes `.testspectra/types/` ambient declarations
|
|
37
|
-
* automatically in the background whenever the project is opened or files change.
|
|
38
|
-
*/
|
|
39
|
-
function init(modules) {
|
|
40
|
-
const tsModule = modules.typescript;
|
|
41
|
-
function create(info) {
|
|
42
|
-
const project = info.project;
|
|
43
|
-
const configPath = typeof project.getConfigFilePath === "function" ? project.getConfigFilePath() : "";
|
|
44
|
-
const projectDir = configPath ? path.dirname(configPath) : project.getCurrentDirectory();
|
|
45
|
-
const workspaceRoot = findWorkspaceRoot(projectDir);
|
|
46
|
-
const log = (msg) => {
|
|
47
|
-
try {
|
|
48
|
-
info.project.projectService.logger.info(`[TestSpectra TS Plugin] ${msg}`);
|
|
49
|
-
}
|
|
50
|
-
catch { }
|
|
51
|
-
appendLog(workspaceRoot, msg);
|
|
52
|
-
};
|
|
53
|
-
log(`Plugin initialized on project: ${projectDir} (resolved root: ${workspaceRoot})`);
|
|
54
|
-
// 1. Initial Generation on project load
|
|
55
|
-
try {
|
|
56
|
-
TypeGenerator.writeDeclarationFiles(workspaceRoot);
|
|
57
|
-
if (typeof project.markAsDirty === "function") {
|
|
58
|
-
project.markAsDirty();
|
|
59
|
-
}
|
|
60
|
-
log(`Generated ambient declarations on startup`);
|
|
61
|
-
}
|
|
62
|
-
catch (err) {
|
|
63
|
-
log(`Failed initial type generation: ${err?.message}`);
|
|
64
|
-
}
|
|
65
|
-
// Debounced regeneration handler
|
|
66
|
-
let debounceTimer = null;
|
|
67
|
-
const triggerRegeneration = (reason, sync = false) => {
|
|
68
|
-
const doRegen = () => {
|
|
69
|
-
try {
|
|
70
|
-
TypeGenerator.writeDeclarationFiles(workspaceRoot);
|
|
71
|
-
if (typeof project.markAsDirty === "function") {
|
|
72
|
-
project.markAsDirty();
|
|
73
|
-
}
|
|
74
|
-
log(`Regenerated ambient declarations (${reason})`);
|
|
75
|
-
}
|
|
76
|
-
catch (err) {
|
|
77
|
-
log(`Error during regeneration: ${err?.message}`);
|
|
78
|
-
}
|
|
79
|
-
};
|
|
80
|
-
if (sync) {
|
|
81
|
-
doRegen();
|
|
82
|
-
}
|
|
83
|
-
else {
|
|
84
|
-
if (debounceTimer)
|
|
85
|
-
clearTimeout(debounceTimer);
|
|
86
|
-
debounceTimer = setTimeout(doRegen, 80);
|
|
87
|
-
}
|
|
88
|
-
};
|
|
89
|
-
// 2. Active File System Watcher on the entire workspace
|
|
90
|
-
try {
|
|
91
|
-
if (fs.existsSync(workspaceRoot)) {
|
|
92
|
-
const watcher = fs.watch(workspaceRoot, { recursive: true }, (eventType, filename) => {
|
|
93
|
-
if (!filename)
|
|
94
|
-
return;
|
|
95
|
-
const fn = filename.toString();
|
|
96
|
-
// Skip internal and build directories
|
|
97
|
-
if (fn.includes(".testspectra") ||
|
|
98
|
-
fn.includes("node_modules") ||
|
|
99
|
-
fn.includes(".git") ||
|
|
100
|
-
fn.includes("dist") ||
|
|
101
|
-
fn.includes(".nx")) {
|
|
102
|
-
return;
|
|
103
|
-
}
|
|
104
|
-
// Match relevant entity files
|
|
105
|
-
if (fn.includes("fixtures") ||
|
|
106
|
-
fn.includes("page-objects") ||
|
|
107
|
-
fn.includes("pageobjects") ||
|
|
108
|
-
fn.includes("actions") ||
|
|
109
|
-
fn.includes("steps") ||
|
|
110
|
-
fn.includes("hooks") ||
|
|
111
|
-
fn.includes("spectra.config")) {
|
|
112
|
-
log(`Detected file change [${eventType}]: ${fn}`);
|
|
113
|
-
triggerRegeneration(`fs.watch '${eventType}' on ${fn}`);
|
|
114
|
-
}
|
|
115
|
-
});
|
|
116
|
-
watcher.on("error", () => { });
|
|
117
|
-
log(`Attached recursive fs.watch on ${workspaceRoot}`);
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
catch (err) {
|
|
121
|
-
log(`Note: Recursive fs.watch not supported or failed: ${err?.message}`);
|
|
122
|
-
}
|
|
123
|
-
// 3. Proxy language service methods to detect file modifications / completions
|
|
124
|
-
if (!info.languageService) {
|
|
125
|
-
return Object.create(null);
|
|
126
|
-
}
|
|
127
|
-
const proxy = Object.create(null);
|
|
128
|
-
for (const k of Object.keys(info.languageService)) {
|
|
129
|
-
const x = info.languageService[k];
|
|
130
|
-
// @ts-ignore
|
|
131
|
-
proxy[k] = (...args) => x.apply(info.languageService, args);
|
|
132
|
-
}
|
|
133
|
-
// Intercept getCompletionsAtPosition to ensure fresh types
|
|
134
|
-
const originalGetCompletions = info.languageService.getCompletionsAtPosition;
|
|
135
|
-
proxy.getCompletionsAtPosition = (fileName, position, options, formattingSettings) => {
|
|
136
|
-
const ext = path.extname(fileName);
|
|
137
|
-
if (ext === ".ts" || ext === ".tsx" || ext === ".js" || ext === ".mjs") {
|
|
138
|
-
triggerRegeneration(`completions at ${path.basename(fileName)}`, false);
|
|
139
|
-
}
|
|
140
|
-
return originalGetCompletions.apply(info.languageService, [
|
|
141
|
-
fileName,
|
|
142
|
-
position,
|
|
143
|
-
options,
|
|
144
|
-
formattingSettings,
|
|
145
|
-
]);
|
|
146
|
-
};
|
|
147
|
-
// Intercept getQuickInfoAtPosition for fresh hover info
|
|
148
|
-
const originalGetQuickInfo = info.languageService.getQuickInfoAtPosition;
|
|
149
|
-
proxy.getQuickInfoAtPosition = (fileName, position) => {
|
|
150
|
-
return originalGetQuickInfo.apply(info.languageService, [fileName, position]);
|
|
151
|
-
};
|
|
152
|
-
return proxy;
|
|
153
|
-
}
|
|
154
|
-
function getExternalFiles(project) {
|
|
155
|
-
try {
|
|
156
|
-
const workspaceRoot = findWorkspaceRoot(project.getCurrentDirectory());
|
|
157
|
-
const typesDir = path.join(workspaceRoot, ".testspectra", "types");
|
|
158
|
-
const files = [];
|
|
159
|
-
function collectDts(dir) {
|
|
160
|
-
if (!fs.existsSync(dir))
|
|
161
|
-
return;
|
|
162
|
-
const entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
163
|
-
for (const entry of entries) {
|
|
164
|
-
const fullPath = path.join(dir, entry.name);
|
|
165
|
-
if (entry.isDirectory()) {
|
|
166
|
-
collectDts(fullPath);
|
|
167
|
-
}
|
|
168
|
-
else if (entry.isFile() && entry.name.endsWith(".d.ts")) {
|
|
169
|
-
files.push(fullPath);
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
collectDts(typesDir);
|
|
174
|
-
return files;
|
|
175
|
-
}
|
|
176
|
-
catch {
|
|
177
|
-
return [];
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
return { create, getExternalFiles };
|
|
181
|
-
}
|
|
182
|
-
init.TypeGenerator = TypeGenerator;
|
|
183
|
-
export default init;
|
|
184
|
-
export { init };
|
package/dist/step/index.d.ts
DELETED
package/dist/step/index.js
DELETED
package/dist/step/matchers.d.ts
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import { SingleElementMatcher, MultiElementMatcher, ElementTarget } from "./types.js";
|
|
2
|
-
/**
|
|
3
|
-
* Resolves an ElementTarget (selector string, WebdriverIO.Element, or ChainablePromiseElement)
|
|
4
|
-
* to an actionable WebdriverIO.Element.
|
|
5
|
-
*/
|
|
6
|
-
export declare function resolveElement(target: ElementTarget): Promise<WebdriverIO.Element>;
|
|
7
|
-
/**
|
|
8
|
-
* Executes a single element matcher against the WebdriverIO browser / element context.
|
|
9
|
-
*/
|
|
10
|
-
export declare function executeSingleMatcher(target: ElementTarget | undefined, matcher: SingleElementMatcher, args: any[]): Promise<void>;
|
|
11
|
-
/**
|
|
12
|
-
* Executes a multi-element collection matcher against WebdriverIO $$.
|
|
13
|
-
*/
|
|
14
|
-
export declare function executeMultiMatcher(selector: string, matcher: MultiElementMatcher, args: any[]): Promise<void>;
|
package/dist/step/matchers.js
DELETED
|
@@ -1,114 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Resolves an ElementTarget (selector string, WebdriverIO.Element, or ChainablePromiseElement)
|
|
3
|
-
* to an actionable WebdriverIO.Element.
|
|
4
|
-
*/
|
|
5
|
-
export async function resolveElement(target) {
|
|
6
|
-
if (typeof target === "string") {
|
|
7
|
-
const el = await $(target);
|
|
8
|
-
return el;
|
|
9
|
-
}
|
|
10
|
-
const el = await target;
|
|
11
|
-
return el;
|
|
12
|
-
}
|
|
13
|
-
/**
|
|
14
|
-
* Executes a single element matcher against the WebdriverIO browser / element context.
|
|
15
|
-
*/
|
|
16
|
-
export async function executeSingleMatcher(target, matcher, args) {
|
|
17
|
-
const isBrowserLevel = matcher === "have.url" ||
|
|
18
|
-
matcher === "contain.url" ||
|
|
19
|
-
matcher === "have.title" ||
|
|
20
|
-
matcher === "contain.title";
|
|
21
|
-
if (isBrowserLevel) {
|
|
22
|
-
const expected = args[0];
|
|
23
|
-
switch (matcher) {
|
|
24
|
-
case "have.url":
|
|
25
|
-
await expect(browser).toHaveUrl(expected);
|
|
26
|
-
break;
|
|
27
|
-
case "contain.url":
|
|
28
|
-
await expect(browser).toHaveUrl(expect.stringContaining(expected));
|
|
29
|
-
break;
|
|
30
|
-
case "have.title":
|
|
31
|
-
await expect(browser).toHaveTitle(expected);
|
|
32
|
-
break;
|
|
33
|
-
case "contain.title":
|
|
34
|
-
await expect(browser).toHaveTitle(expect.stringContaining(expected));
|
|
35
|
-
break;
|
|
36
|
-
}
|
|
37
|
-
return;
|
|
38
|
-
}
|
|
39
|
-
if (!target) {
|
|
40
|
-
throw new Error(`Assertion matcher '${matcher}' requires an element target.`);
|
|
41
|
-
}
|
|
42
|
-
const el = await resolveElement(target);
|
|
43
|
-
switch (matcher) {
|
|
44
|
-
case "be.visible":
|
|
45
|
-
await expect(el).toBeDisplayed();
|
|
46
|
-
break;
|
|
47
|
-
case "not.be.visible":
|
|
48
|
-
await expect(el).not.toBeDisplayed();
|
|
49
|
-
break;
|
|
50
|
-
case "exist":
|
|
51
|
-
await expect(el).toExist();
|
|
52
|
-
break;
|
|
53
|
-
case "not.exist":
|
|
54
|
-
await expect(el).not.toExist();
|
|
55
|
-
break;
|
|
56
|
-
case "be.enabled":
|
|
57
|
-
await expect(el).toBeEnabled();
|
|
58
|
-
break;
|
|
59
|
-
case "be.disabled":
|
|
60
|
-
await expect(el).toBeDisabled();
|
|
61
|
-
break;
|
|
62
|
-
case "be.checked":
|
|
63
|
-
case "be.selected":
|
|
64
|
-
await expect(el).toBeSelected();
|
|
65
|
-
break;
|
|
66
|
-
case "have.value":
|
|
67
|
-
await expect(el).toHaveValue(args[0]);
|
|
68
|
-
break;
|
|
69
|
-
case "contain.value":
|
|
70
|
-
await expect(el).toHaveValue(expect.stringContaining(args[0]));
|
|
71
|
-
break;
|
|
72
|
-
case "have.text":
|
|
73
|
-
await expect(el).toHaveText(args[0]);
|
|
74
|
-
break;
|
|
75
|
-
case "contain.text":
|
|
76
|
-
await expect(el).toHaveText(expect.stringContaining(args[0]));
|
|
77
|
-
break;
|
|
78
|
-
case "have.class":
|
|
79
|
-
await expect(el).toHaveElementClass(args[0]);
|
|
80
|
-
break;
|
|
81
|
-
case "have.attr":
|
|
82
|
-
if (args.length >= 2) {
|
|
83
|
-
await expect(el).toHaveAttribute(args[0], args[1]);
|
|
84
|
-
}
|
|
85
|
-
else {
|
|
86
|
-
await expect(el).toHaveAttribute(args[0]);
|
|
87
|
-
}
|
|
88
|
-
break;
|
|
89
|
-
default:
|
|
90
|
-
throw new Error(`Unsupported matcher: ${matcher}`);
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
/**
|
|
94
|
-
* Executes a multi-element collection matcher against WebdriverIO $$.
|
|
95
|
-
*/
|
|
96
|
-
export async function executeMultiMatcher(selector, matcher, args) {
|
|
97
|
-
const elements = await $$(selector);
|
|
98
|
-
switch (matcher) {
|
|
99
|
-
case "have.length":
|
|
100
|
-
await expect(elements).toBeElementsArrayOfSize(args[0]);
|
|
101
|
-
break;
|
|
102
|
-
case "have.length.greaterThan":
|
|
103
|
-
await expect(elements).toBeElementsArrayOfSize({ gte: args[0] + 1 });
|
|
104
|
-
break;
|
|
105
|
-
case "be.empty":
|
|
106
|
-
await expect(elements).toBeElementsArrayOfSize(0);
|
|
107
|
-
break;
|
|
108
|
-
case "exist":
|
|
109
|
-
await expect(elements).toBeElementsArrayOfSize({ gte: 1 });
|
|
110
|
-
break;
|
|
111
|
-
default:
|
|
112
|
-
throw new Error(`Unsupported multi-element matcher: ${matcher}`);
|
|
113
|
-
}
|
|
114
|
-
}
|
package/dist/step/proto.d.ts
DELETED
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
declare global {
|
|
2
|
-
namespace WebdriverIO {
|
|
3
|
-
interface Element {
|
|
4
|
-
shouldBeVisible(): Promise<Element>;
|
|
5
|
-
shouldNotBeVisible(): Promise<Element>;
|
|
6
|
-
shouldExist(): Promise<Element>;
|
|
7
|
-
shouldNotExist(): Promise<Element>;
|
|
8
|
-
shouldBeEnabled(): Promise<Element>;
|
|
9
|
-
shouldBeDisabled(): Promise<Element>;
|
|
10
|
-
shouldBeSelected(): Promise<Element>;
|
|
11
|
-
shouldBeChecked(): Promise<Element>;
|
|
12
|
-
shouldHaveValue(expectedValue: string): Promise<Element>;
|
|
13
|
-
shouldContainValue(expectedValue: string): Promise<Element>;
|
|
14
|
-
shouldHaveText(expectedText: string): Promise<Element>;
|
|
15
|
-
shouldContainText(expectedText: string): Promise<Element>;
|
|
16
|
-
shouldHaveClass(className: string): Promise<Element>;
|
|
17
|
-
shouldHaveAttribute(attributeName: string, expectedValue?: string): Promise<Element>;
|
|
18
|
-
}
|
|
19
|
-
interface Browser {
|
|
20
|
-
shouldHaveUrl(expectedUrl: string): Promise<void>;
|
|
21
|
-
shouldContainUrl(expectedUrl: string): Promise<void>;
|
|
22
|
-
shouldHaveTitle(expectedTitle: string): Promise<void>;
|
|
23
|
-
shouldContainTitle(expectedTitle: string): Promise<void>;
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
interface Promise<T> {
|
|
27
|
-
shouldBeVisible(this: Promise<WebdriverIO.Element>): Promise<WebdriverIO.Element>;
|
|
28
|
-
shouldNotBeVisible(this: Promise<WebdriverIO.Element>): Promise<WebdriverIO.Element>;
|
|
29
|
-
shouldExist(this: Promise<WebdriverIO.Element>): Promise<WebdriverIO.Element>;
|
|
30
|
-
shouldNotExist(this: Promise<WebdriverIO.Element>): Promise<WebdriverIO.Element>;
|
|
31
|
-
shouldBeEnabled(this: Promise<WebdriverIO.Element>): Promise<WebdriverIO.Element>;
|
|
32
|
-
shouldBeDisabled(this: Promise<WebdriverIO.Element>): Promise<WebdriverIO.Element>;
|
|
33
|
-
shouldBeSelected(this: Promise<WebdriverIO.Element>): Promise<WebdriverIO.Element>;
|
|
34
|
-
shouldBeChecked(this: Promise<WebdriverIO.Element>): Promise<WebdriverIO.Element>;
|
|
35
|
-
shouldHaveValue(this: Promise<WebdriverIO.Element>, expectedValue: string): Promise<WebdriverIO.Element>;
|
|
36
|
-
shouldContainValue(this: Promise<WebdriverIO.Element>, expectedValue: string): Promise<WebdriverIO.Element>;
|
|
37
|
-
shouldHaveText(this: Promise<WebdriverIO.Element>, expectedText: string): Promise<WebdriverIO.Element>;
|
|
38
|
-
shouldContainText(this: Promise<WebdriverIO.Element>, expectedText: string): Promise<WebdriverIO.Element>;
|
|
39
|
-
shouldHaveClass(this: Promise<WebdriverIO.Element>, className: string): Promise<WebdriverIO.Element>;
|
|
40
|
-
shouldHaveAttribute(this: Promise<WebdriverIO.Element>, attributeName: string, expectedValue?: string): Promise<WebdriverIO.Element>;
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
/**
|
|
44
|
-
* Install direct callable assertion methods onto WebdriverIO browser/element and Promise prototypes.
|
|
45
|
-
*/
|
|
46
|
-
export declare function installPrototypes(): void;
|
package/dist/step/proto.js
DELETED
|
@@ -1,114 +0,0 @@
|
|
|
1
|
-
import { resolveElement } from "./matchers.js";
|
|
2
|
-
/**
|
|
3
|
-
* Install direct callable assertion methods onto WebdriverIO browser/element and Promise prototypes.
|
|
4
|
-
*/
|
|
5
|
-
export function installPrototypes() {
|
|
6
|
-
const elementCommands = {
|
|
7
|
-
async shouldBeVisible() {
|
|
8
|
-
const el = await resolveElement(this);
|
|
9
|
-
await expect(el).toBeDisplayed();
|
|
10
|
-
return el;
|
|
11
|
-
},
|
|
12
|
-
async shouldNotBeVisible() {
|
|
13
|
-
const el = await resolveElement(this);
|
|
14
|
-
await expect(el).not.toBeDisplayed();
|
|
15
|
-
return el;
|
|
16
|
-
},
|
|
17
|
-
async shouldExist() {
|
|
18
|
-
const el = await resolveElement(this);
|
|
19
|
-
await expect(el).toExist();
|
|
20
|
-
return el;
|
|
21
|
-
},
|
|
22
|
-
async shouldNotExist() {
|
|
23
|
-
const el = await resolveElement(this);
|
|
24
|
-
await expect(el).not.toExist();
|
|
25
|
-
return el;
|
|
26
|
-
},
|
|
27
|
-
async shouldBeEnabled() {
|
|
28
|
-
const el = await resolveElement(this);
|
|
29
|
-
await expect(el).toBeEnabled();
|
|
30
|
-
return el;
|
|
31
|
-
},
|
|
32
|
-
async shouldBeDisabled() {
|
|
33
|
-
const el = await resolveElement(this);
|
|
34
|
-
await expect(el).toBeDisabled();
|
|
35
|
-
return el;
|
|
36
|
-
},
|
|
37
|
-
async shouldBeSelected() {
|
|
38
|
-
const el = await resolveElement(this);
|
|
39
|
-
await expect(el).toBeSelected();
|
|
40
|
-
return el;
|
|
41
|
-
},
|
|
42
|
-
async shouldBeChecked() {
|
|
43
|
-
const el = await resolveElement(this);
|
|
44
|
-
await expect(el).toBeSelected();
|
|
45
|
-
return el;
|
|
46
|
-
},
|
|
47
|
-
async shouldHaveValue(val) {
|
|
48
|
-
const el = await resolveElement(this);
|
|
49
|
-
await expect(el).toHaveValue(val);
|
|
50
|
-
return el;
|
|
51
|
-
},
|
|
52
|
-
async shouldContainValue(val) {
|
|
53
|
-
const el = await resolveElement(this);
|
|
54
|
-
await expect(el).toHaveValue(expect.stringContaining(val));
|
|
55
|
-
return el;
|
|
56
|
-
},
|
|
57
|
-
async shouldHaveText(text) {
|
|
58
|
-
const el = await resolveElement(this);
|
|
59
|
-
await expect(el).toHaveText(text);
|
|
60
|
-
return el;
|
|
61
|
-
},
|
|
62
|
-
async shouldContainText(text) {
|
|
63
|
-
const el = await resolveElement(this);
|
|
64
|
-
await expect(el).toHaveText(expect.stringContaining(text));
|
|
65
|
-
return el;
|
|
66
|
-
},
|
|
67
|
-
async shouldHaveClass(cls) {
|
|
68
|
-
const el = await resolveElement(this);
|
|
69
|
-
await expect(el).toHaveElementClass(cls);
|
|
70
|
-
return el;
|
|
71
|
-
},
|
|
72
|
-
async shouldHaveAttribute(name, val) {
|
|
73
|
-
const el = await resolveElement(this);
|
|
74
|
-
if (val !== undefined) {
|
|
75
|
-
await expect(el).toHaveAttribute(name, val);
|
|
76
|
-
}
|
|
77
|
-
else {
|
|
78
|
-
await expect(el).toHaveAttribute(name);
|
|
79
|
-
}
|
|
80
|
-
return el;
|
|
81
|
-
},
|
|
82
|
-
};
|
|
83
|
-
const browserCommands = {
|
|
84
|
-
async shouldHaveUrl(url) {
|
|
85
|
-
await expect(browser).toHaveUrl(url);
|
|
86
|
-
},
|
|
87
|
-
async shouldContainUrl(url) {
|
|
88
|
-
await expect(browser).toHaveUrl(expect.stringContaining(url));
|
|
89
|
-
},
|
|
90
|
-
async shouldHaveTitle(title) {
|
|
91
|
-
await expect(browser).toHaveTitle(title);
|
|
92
|
-
},
|
|
93
|
-
async shouldContainTitle(title) {
|
|
94
|
-
await expect(browser).toHaveTitle(expect.stringContaining(title));
|
|
95
|
-
},
|
|
96
|
-
};
|
|
97
|
-
if (typeof browser !== "undefined" && browser.addCommand) {
|
|
98
|
-
for (const [name, fn] of Object.entries(elementCommands)) {
|
|
99
|
-
browser.addCommand(name, fn, true);
|
|
100
|
-
}
|
|
101
|
-
for (const [name, fn] of Object.entries(browserCommands)) {
|
|
102
|
-
browser.addCommand(name, fn, false);
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
// Attach to Promise.prototype for ChainablePromiseElement unwrapping
|
|
106
|
-
for (const [name, fn] of Object.entries(elementCommands)) {
|
|
107
|
-
if (typeof Promise.prototype[name] !== "function") {
|
|
108
|
-
Promise.prototype[name] = async function (...args) {
|
|
109
|
-
const el = await this;
|
|
110
|
-
return await fn.call(el, ...args);
|
|
111
|
-
};
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import { MultiElementMatcher } from "../types.js";
|
|
2
|
-
import { SingleElementRunner } from "./single.js";
|
|
3
|
-
export declare class MultiElementRunner implements PromiseLike<void> {
|
|
4
|
-
private _selector;
|
|
5
|
-
private _assertions;
|
|
6
|
-
constructor(selector: string);
|
|
7
|
-
should(matcher: MultiElementMatcher, ...args: any[]): this;
|
|
8
|
-
eq(index: number): SingleElementRunner;
|
|
9
|
-
first(): SingleElementRunner;
|
|
10
|
-
last(): SingleElementRunner;
|
|
11
|
-
each(callback: (el: SingleElementRunner, index: number) => Promise<void>): Promise<void>;
|
|
12
|
-
then<TResult1 = void, TResult2 = never>(onfulfilled?: ((value: void) => TResult1 | PromiseLike<TResult1>) | null, onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | null): Promise<TResult1 | TResult2>;
|
|
13
|
-
}
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
import { executeMultiMatcher } from "../matchers.js";
|
|
2
|
-
import { SingleElementRunner } from "./single.js";
|
|
3
|
-
export class MultiElementRunner {
|
|
4
|
-
_selector;
|
|
5
|
-
_assertions = [];
|
|
6
|
-
constructor(selector) {
|
|
7
|
-
this._selector = selector;
|
|
8
|
-
}
|
|
9
|
-
// --- Collection Assertions ---
|
|
10
|
-
should(matcher, ...args) {
|
|
11
|
-
this._assertions.push({ matcher, args });
|
|
12
|
-
return this;
|
|
13
|
-
}
|
|
14
|
-
// --- Item Navigation ---
|
|
15
|
-
eq(index) {
|
|
16
|
-
const indexedSelector = `(${this._selector})[${index + 1}]`;
|
|
17
|
-
return new SingleElementRunner(indexedSelector);
|
|
18
|
-
}
|
|
19
|
-
first() {
|
|
20
|
-
return this.eq(0);
|
|
21
|
-
}
|
|
22
|
-
last() {
|
|
23
|
-
const indexedSelector = `(${this._selector})[last()]`;
|
|
24
|
-
return new SingleElementRunner(indexedSelector);
|
|
25
|
-
}
|
|
26
|
-
// --- Iteration Callback ---
|
|
27
|
-
async each(callback) {
|
|
28
|
-
const elements = await $$(this._selector);
|
|
29
|
-
const count = await elements.length;
|
|
30
|
-
for (let i = 0; i < count; i++) {
|
|
31
|
-
const runner = this.eq(i);
|
|
32
|
-
await callback(runner, i);
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
// --- Execution when awaited ---
|
|
36
|
-
async then(onfulfilled, onrejected) {
|
|
37
|
-
try {
|
|
38
|
-
for (const assert of this._assertions) {
|
|
39
|
-
await executeMultiMatcher(this._selector, assert.matcher, assert.args);
|
|
40
|
-
}
|
|
41
|
-
const res = (onfulfilled ? await onfulfilled() : undefined);
|
|
42
|
-
return res;
|
|
43
|
-
}
|
|
44
|
-
catch (err) {
|
|
45
|
-
if (onrejected) {
|
|
46
|
-
return onrejected(err);
|
|
47
|
-
}
|
|
48
|
-
throw err;
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
}
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import { SingleElementMatcher, ElementTarget } from "../types.js";
|
|
2
|
-
export declare class SingleElementRunner implements PromiseLike<void> {
|
|
3
|
-
private _target;
|
|
4
|
-
private _action;
|
|
5
|
-
private _assertions;
|
|
6
|
-
constructor(target?: ElementTarget, action?: () => Promise<any>);
|
|
7
|
-
click(): this;
|
|
8
|
-
doubleClick(): this;
|
|
9
|
-
longPress(durationMs?: number): this;
|
|
10
|
-
type(value: string, options?: {
|
|
11
|
-
clearFirst?: boolean;
|
|
12
|
-
}): this;
|
|
13
|
-
clear(): this;
|
|
14
|
-
select(value: string): this;
|
|
15
|
-
hover(): this;
|
|
16
|
-
waitForElement(timeoutMs?: number): this;
|
|
17
|
-
should(matcher: SingleElementMatcher, ...args: any[]): this;
|
|
18
|
-
should(target: ElementTarget, matcher: SingleElementMatcher, ...args: any[]): this;
|
|
19
|
-
then<TResult1 = void, TResult2 = never>(onfulfilled?: ((value: void) => TResult1 | PromiseLike<TResult1>) | null, onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | null): Promise<TResult1 | TResult2>;
|
|
20
|
-
private requireTarget;
|
|
21
|
-
}
|