@testspectra/matchers 1.1.11-rc.5 → 1.1.13
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/__tests__/matcher-contracts.test.d.ts +1 -0
- package/dist/__tests__/matcher-contracts.test.js +498 -0
- package/dist/contract.d.ts +5 -42
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/matchers.d.ts +10 -3
- package/dist/matchers.js +576 -135
- package/dist/proto.d.ts +1 -0
- package/dist/reporter.js +13 -1
- package/dist/runner/collection.js +32 -6
- package/dist/runner/single.d.ts +2 -2
- package/dist/runner/single.js +24 -7
- package/dist/semantic.d.ts +11 -0
- package/dist/semantic.js +141 -0
- package/dist/types.d.ts +34 -1
- package/dist/worker_config.d.ts +97 -0
- package/dist/worker_config.js +17 -0
- package/package.json +1 -1
- package/src/contract.ts +5 -36
- package/src/index.ts +1 -0
- package/src/proto.ts +2 -0
- package/src/types.ts +37 -0
- package/src/worker_config.ts +102 -0
- package/testspectra-matchers-1.1.13.tgz +0 -0
- package/tsconfig.json +1 -1
- package/src/runtime/assertions.ts +0 -454
- package/src/runtime/element_actions.ts +0 -169
- package/src/runtime/element_proxy.ts +0 -199
- package/src/runtime/element_state.ts +0 -94
- package/src/runtime/spectra.ts +0 -110
- package/testspectra-matchers-1.1.11-rc.5.tgz +0 -0
|
@@ -1,169 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Element action methods for `SingleElementProxy`.
|
|
3
|
-
*
|
|
4
|
-
* Each action delegates to the bound `PlatformDriverBridge` and wraps the invocation in a
|
|
5
|
-
* semantic `trackStep('action')` log entry. There is zero platform branching here — every
|
|
6
|
-
* platform-specific behavior lives inside the active driver.
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
import type { ClickOptions, ElementTarget, LongPressOptions, ScopedSelector, TypeOptions } from '@testspectra/matchers';
|
|
10
|
-
|
|
11
|
-
export function createElementActions(selector: string | ScopedSelector, index: number | null): Record<string, any> {
|
|
12
|
-
const driver = () => globalThis.__TS_RUNTIME__.activeDriver!;
|
|
13
|
-
|
|
14
|
-
async function click(_options?: ClickOptions): Promise<void> {
|
|
15
|
-
return globalThis.__TS_RUNTIME__.trackStep(
|
|
16
|
-
'action',
|
|
17
|
-
{ type: 'action', key: 'click', target: selector, args: [] },
|
|
18
|
-
async () => {
|
|
19
|
-
await driver().click(selector, index);
|
|
20
|
-
},
|
|
21
|
-
);
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
async function doubleClick(): Promise<void> {
|
|
25
|
-
return globalThis.__TS_RUNTIME__.trackStep(
|
|
26
|
-
'action',
|
|
27
|
-
{ type: 'action', key: 'doubleClick', target: selector, args: [] },
|
|
28
|
-
async () => {
|
|
29
|
-
await driver().doubleClick(selector, index);
|
|
30
|
-
},
|
|
31
|
-
);
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
async function rightClick(): Promise<void> {
|
|
35
|
-
return globalThis.__TS_RUNTIME__.trackStep(
|
|
36
|
-
'action',
|
|
37
|
-
{ type: 'action', key: 'rightClick', target: selector, args: [] },
|
|
38
|
-
async () => {
|
|
39
|
-
await driver().rightClick(selector, index);
|
|
40
|
-
},
|
|
41
|
-
);
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
async function setValue(value: unknown): Promise<void> {
|
|
45
|
-
return globalThis.__TS_RUNTIME__.trackStep(
|
|
46
|
-
'action',
|
|
47
|
-
{ type: 'action', key: 'type', target: selector, args: [value] },
|
|
48
|
-
async () => {
|
|
49
|
-
await driver().setValue(selector, value, index);
|
|
50
|
-
},
|
|
51
|
-
);
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
async function type(value: unknown, options?: TypeOptions): Promise<void> {
|
|
55
|
-
if (options?.clearFirst) {
|
|
56
|
-
await clearValue();
|
|
57
|
-
}
|
|
58
|
-
await setValue(value);
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
async function clearValue(): Promise<void> {
|
|
62
|
-
return globalThis.__TS_RUNTIME__.trackStep(
|
|
63
|
-
'action',
|
|
64
|
-
{ type: 'action', key: 'clear', target: selector, args: [] },
|
|
65
|
-
async () => {
|
|
66
|
-
await driver().clearValue(selector, index);
|
|
67
|
-
},
|
|
68
|
-
);
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
async function clear(): Promise<void> {
|
|
72
|
-
await clearValue();
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
async function select(option: string): Promise<void> {
|
|
76
|
-
return globalThis.__TS_RUNTIME__.trackStep(
|
|
77
|
-
'action',
|
|
78
|
-
{ type: 'action', key: 'select', target: selector, args: [option] },
|
|
79
|
-
async () => {
|
|
80
|
-
await driver().select(selector, option, index);
|
|
81
|
-
},
|
|
82
|
-
);
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
async function selectByVisibleText(text: string): Promise<void> {
|
|
86
|
-
await select(text);
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
async function hover(): Promise<void> {
|
|
90
|
-
return globalThis.__TS_RUNTIME__.trackStep(
|
|
91
|
-
'action',
|
|
92
|
-
{ type: 'action', key: 'hover', target: selector, args: [] },
|
|
93
|
-
async () => {
|
|
94
|
-
await driver().hover(selector, index);
|
|
95
|
-
},
|
|
96
|
-
);
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
async function focus(): Promise<void> {
|
|
100
|
-
return globalThis.__TS_RUNTIME__.trackStep(
|
|
101
|
-
'action',
|
|
102
|
-
{ type: 'action', key: 'focus', target: selector, args: [] },
|
|
103
|
-
async () => {
|
|
104
|
-
await driver().focus(selector, index);
|
|
105
|
-
},
|
|
106
|
-
);
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
async function moveTo(): Promise<void> {
|
|
110
|
-
await hover();
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
async function dragDrop(target: ElementTarget): Promise<void> {
|
|
114
|
-
const destSelector = typeof target === 'string' ? target : (target as any)?.selector || String(target);
|
|
115
|
-
return globalThis.__TS_RUNTIME__.trackStep(
|
|
116
|
-
'action',
|
|
117
|
-
{ type: 'action', key: 'dragDrop', target: selector, args: [destSelector] },
|
|
118
|
-
async () => {
|
|
119
|
-
await driver().dragDrop(selector, destSelector, index);
|
|
120
|
-
},
|
|
121
|
-
);
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
async function dragAndDrop(target: ElementTarget): Promise<void> {
|
|
125
|
-
await dragDrop(target);
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
async function longPress(options?: number | LongPressOptions): Promise<void> {
|
|
129
|
-
const duration = typeof options === 'number' ? options : options?.duration || 1000;
|
|
130
|
-
return globalThis.__TS_RUNTIME__.trackStep(
|
|
131
|
-
'action',
|
|
132
|
-
{ type: 'action', key: 'longPress', target: selector, args: [duration] },
|
|
133
|
-
async () => {
|
|
134
|
-
await driver().longPress(selector, duration, index);
|
|
135
|
-
},
|
|
136
|
-
);
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
async function scrollIntoView(): Promise<void> {
|
|
140
|
-
return globalThis.__TS_RUNTIME__.trackStep(
|
|
141
|
-
'action',
|
|
142
|
-
{ type: 'action', key: 'scrollIntoView', target: selector, args: [] },
|
|
143
|
-
async () => {
|
|
144
|
-
await driver().scrollIntoView(selector, index);
|
|
145
|
-
},
|
|
146
|
-
);
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
return {
|
|
150
|
-
click,
|
|
151
|
-
doubleClick,
|
|
152
|
-
rightClick,
|
|
153
|
-
setValue,
|
|
154
|
-
type,
|
|
155
|
-
clearValue,
|
|
156
|
-
clear,
|
|
157
|
-
select,
|
|
158
|
-
selectByVisibleText,
|
|
159
|
-
hover,
|
|
160
|
-
focus,
|
|
161
|
-
moveTo,
|
|
162
|
-
dragDrop,
|
|
163
|
-
dragAndDrop,
|
|
164
|
-
longPress,
|
|
165
|
-
scrollIntoView,
|
|
166
|
-
};
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
globalThis.__TS_RUNTIME__.createElementActions = createElementActions;
|
|
@@ -1,199 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Element & collection proxy factories plus target resolution.
|
|
3
|
-
*
|
|
4
|
-
* Assembles action, state-inspection, and assertion methods into `SingleElementProxy` and
|
|
5
|
-
* `CollectionProxy` instances that dispatch to the bound `PlatformDriverBridge`. The sibling
|
|
6
|
-
* factories are read from the shared runtime context (single-scope concatenated assembly).
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
import type {
|
|
10
|
-
AssertionOptions,
|
|
11
|
-
CollectionProxy,
|
|
12
|
-
ElementTarget,
|
|
13
|
-
ScopedSelector,
|
|
14
|
-
SingleElementProxy,
|
|
15
|
-
} from '@testspectra/matchers';
|
|
16
|
-
|
|
17
|
-
/** Display text for error messages / debugging — the local selector only, never the full chain. */
|
|
18
|
-
function selectorText(s: string | ScopedSelector): string {
|
|
19
|
-
return typeof s === 'string' ? s : s.selector;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
/** Normalizes this element/collection's own identity into a `ScopedSelector`, for use as a
|
|
23
|
-
* child's `parent` when chaining via `.get()`/`.getAll()`. */
|
|
24
|
-
function toScopedSelector(selector: string | ScopedSelector, index: number | null): ScopedSelector {
|
|
25
|
-
return typeof selector === 'string' ? { selector, index, parent: undefined } : selector;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
export function createElementProxy(selector: string | ScopedSelector, index: number | null = null): SingleElementProxy {
|
|
29
|
-
const selectorTextValue = selectorText(selector);
|
|
30
|
-
const resolvedIndex = typeof selector === 'string' ? index : selector.index;
|
|
31
|
-
const actions = globalThis.__TS_RUNTIME__.createElementActions!(selector, index);
|
|
32
|
-
const state = globalThis.__TS_RUNTIME__.createElementState!(selector, index);
|
|
33
|
-
const assertions = globalThis.__TS_RUNTIME__.createElementAssertions!(selector, index, state);
|
|
34
|
-
|
|
35
|
-
return {
|
|
36
|
-
selector: selectorTextValue,
|
|
37
|
-
index: resolvedIndex,
|
|
38
|
-
...actions,
|
|
39
|
-
...state,
|
|
40
|
-
...assertions,
|
|
41
|
-
get(childSelector: string, childIndex: number | null = null): SingleElementProxy {
|
|
42
|
-
return globalThis.__TS_RUNTIME__.createElementProxy!(
|
|
43
|
-
{ selector: childSelector, index: childIndex, parent: toScopedSelector(selector, index) },
|
|
44
|
-
null,
|
|
45
|
-
);
|
|
46
|
-
},
|
|
47
|
-
getAll(childSelector: string): CollectionProxy {
|
|
48
|
-
return globalThis.__TS_RUNTIME__.createCollectionProxy!({
|
|
49
|
-
selector: childSelector,
|
|
50
|
-
index: null,
|
|
51
|
-
parent: toScopedSelector(selector, index),
|
|
52
|
-
});
|
|
53
|
-
},
|
|
54
|
-
} as SingleElementProxy;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
export function createCollectionProxy(selector: string | ScopedSelector): CollectionProxy {
|
|
58
|
-
const driver = () => globalThis.__TS_RUNTIME__.activeDriver!;
|
|
59
|
-
const selectorTextValue = selectorText(selector);
|
|
60
|
-
|
|
61
|
-
/** Builds the (selector, index) pair to hand to `createElementProxy` for first()/last()/nth(),
|
|
62
|
-
* preserving this collection's own scope (parent chain) instead of discarding it. */
|
|
63
|
-
const withIndex = (idx: number): [string | ScopedSelector, number | null] =>
|
|
64
|
-
typeof selector === 'string' ? [selector, idx] : [{ ...selector, index: idx }, null];
|
|
65
|
-
|
|
66
|
-
const collectionProxy: CollectionProxy = {
|
|
67
|
-
selector: selectorTextValue,
|
|
68
|
-
async count(): Promise<number> {
|
|
69
|
-
return await driver().count(selector);
|
|
70
|
-
},
|
|
71
|
-
get length(): Promise<number> {
|
|
72
|
-
return this.count();
|
|
73
|
-
},
|
|
74
|
-
first(): SingleElementProxy {
|
|
75
|
-
return globalThis.__TS_RUNTIME__.createElementProxy!(...withIndex(0));
|
|
76
|
-
},
|
|
77
|
-
last(): SingleElementProxy {
|
|
78
|
-
return globalThis.__TS_RUNTIME__.createElementProxy!(...withIndex(-1));
|
|
79
|
-
},
|
|
80
|
-
nth(index: number): SingleElementProxy {
|
|
81
|
-
return globalThis.__TS_RUNTIME__.createElementProxy!(...withIndex(index));
|
|
82
|
-
},
|
|
83
|
-
async shouldHaveLength(expected: number, options?: AssertionOptions): Promise<void> {
|
|
84
|
-
return globalThis.__TS_RUNTIME__.trackStep(
|
|
85
|
-
'assertion',
|
|
86
|
-
{ type: 'assertion', key: 'have.length', target: selector, args: [expected] },
|
|
87
|
-
async () => {
|
|
88
|
-
let actual = 0;
|
|
89
|
-
const ok = await globalThis.__TS_RUNTIME__.pollCondition(async () => {
|
|
90
|
-
actual = await this.count();
|
|
91
|
-
return actual === expected;
|
|
92
|
-
}, options?.timeoutMs ?? globalThis.__TS_RUNTIME__.getAssertionTimeoutMs());
|
|
93
|
-
if (!ok) {
|
|
94
|
-
throw new Error(`Expected collection "${selectorTextValue}" count to equal ${expected}, but got ${actual}`);
|
|
95
|
-
}
|
|
96
|
-
},
|
|
97
|
-
);
|
|
98
|
-
},
|
|
99
|
-
async shouldNotHaveLength(expected: number, options?: AssertionOptions): Promise<void> {
|
|
100
|
-
return globalThis.__TS_RUNTIME__.trackStep(
|
|
101
|
-
'assertion',
|
|
102
|
-
{ type: 'assertion', key: 'not.have.length', target: selector, args: [expected] },
|
|
103
|
-
async () => {
|
|
104
|
-
let actual = 0;
|
|
105
|
-
const ok = await globalThis.__TS_RUNTIME__.pollCondition(async () => {
|
|
106
|
-
actual = await this.count();
|
|
107
|
-
return actual !== expected;
|
|
108
|
-
}, options?.timeoutMs ?? globalThis.__TS_RUNTIME__.getAssertionTimeoutMs());
|
|
109
|
-
if (!ok) {
|
|
110
|
-
throw new Error(`Expected collection "${selectorTextValue}" count not to equal ${expected}`);
|
|
111
|
-
}
|
|
112
|
-
},
|
|
113
|
-
);
|
|
114
|
-
},
|
|
115
|
-
async shouldHaveLengthGreaterThan(expected: number, options?: AssertionOptions): Promise<void> {
|
|
116
|
-
return globalThis.__TS_RUNTIME__.trackStep(
|
|
117
|
-
'assertion',
|
|
118
|
-
{ type: 'assertion', key: 'have.length.greaterThan', target: selector, args: [expected] },
|
|
119
|
-
async () => {
|
|
120
|
-
let actual = 0;
|
|
121
|
-
const ok = await globalThis.__TS_RUNTIME__.pollCondition(async () => {
|
|
122
|
-
actual = await this.count();
|
|
123
|
-
return actual > expected;
|
|
124
|
-
}, options?.timeoutMs ?? globalThis.__TS_RUNTIME__.getAssertionTimeoutMs());
|
|
125
|
-
if (!ok) {
|
|
126
|
-
throw new Error(
|
|
127
|
-
`Expected collection "${selectorTextValue}" count to be greater than ${expected}, but got ${actual}`,
|
|
128
|
-
);
|
|
129
|
-
}
|
|
130
|
-
},
|
|
131
|
-
);
|
|
132
|
-
},
|
|
133
|
-
async shouldHaveLengthLessThan(expected: number, options?: AssertionOptions): Promise<void> {
|
|
134
|
-
return globalThis.__TS_RUNTIME__.trackStep(
|
|
135
|
-
'assertion',
|
|
136
|
-
{ type: 'assertion', key: 'have.length.lessThan', target: selector, args: [expected] },
|
|
137
|
-
async () => {
|
|
138
|
-
let actual = 0;
|
|
139
|
-
const ok = await globalThis.__TS_RUNTIME__.pollCondition(async () => {
|
|
140
|
-
actual = await this.count();
|
|
141
|
-
return actual < expected;
|
|
142
|
-
}, options?.timeoutMs ?? globalThis.__TS_RUNTIME__.getAssertionTimeoutMs());
|
|
143
|
-
if (!ok) {
|
|
144
|
-
throw new Error(
|
|
145
|
-
`Expected collection "${selectorTextValue}" count to be less than ${expected}, but got ${actual}`,
|
|
146
|
-
);
|
|
147
|
-
}
|
|
148
|
-
},
|
|
149
|
-
);
|
|
150
|
-
},
|
|
151
|
-
async shouldBeEmpty(options?: AssertionOptions): Promise<void> {
|
|
152
|
-
return globalThis.__TS_RUNTIME__.trackStep(
|
|
153
|
-
'assertion',
|
|
154
|
-
{ type: 'assertion', key: 'be.empty', target: selector, args: [] },
|
|
155
|
-
async () => {
|
|
156
|
-
let actual = 0;
|
|
157
|
-
const ok = await globalThis.__TS_RUNTIME__.pollCondition(async () => {
|
|
158
|
-
actual = await this.count();
|
|
159
|
-
return actual === 0;
|
|
160
|
-
}, options?.timeoutMs ?? globalThis.__TS_RUNTIME__.getAssertionTimeoutMs());
|
|
161
|
-
if (!ok) {
|
|
162
|
-
throw new Error(`Expected collection "${selectorTextValue}" to be empty, but got ${actual}`);
|
|
163
|
-
}
|
|
164
|
-
},
|
|
165
|
-
);
|
|
166
|
-
},
|
|
167
|
-
async shouldNotBeEmpty(options?: AssertionOptions): Promise<void> {
|
|
168
|
-
return globalThis.__TS_RUNTIME__.trackStep(
|
|
169
|
-
'assertion',
|
|
170
|
-
{ type: 'assertion', key: 'not.be.empty', target: selector, args: [] },
|
|
171
|
-
async () => {
|
|
172
|
-
let actual = 0;
|
|
173
|
-
const ok = await globalThis.__TS_RUNTIME__.pollCondition(async () => {
|
|
174
|
-
actual = await this.count();
|
|
175
|
-
return actual > 0;
|
|
176
|
-
}, options?.timeoutMs ?? globalThis.__TS_RUNTIME__.getAssertionTimeoutMs());
|
|
177
|
-
if (!ok) {
|
|
178
|
-
throw new Error(`Expected collection "${selectorTextValue}" not to be empty`);
|
|
179
|
-
}
|
|
180
|
-
},
|
|
181
|
-
);
|
|
182
|
-
},
|
|
183
|
-
};
|
|
184
|
-
return collectionProxy;
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
export function resolveTargetProxy(target: ElementTarget): SingleElementProxy {
|
|
188
|
-
if (typeof target === 'string') {
|
|
189
|
-
return (globalThis as any).$(target);
|
|
190
|
-
}
|
|
191
|
-
if (target && typeof target === 'object' && 'selector' in target) {
|
|
192
|
-
return target as SingleElementProxy;
|
|
193
|
-
}
|
|
194
|
-
throw new Error(`Invalid element target: ${String(target)}`);
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
globalThis.__TS_RUNTIME__.createElementProxy = createElementProxy;
|
|
198
|
-
globalThis.__TS_RUNTIME__.createCollectionProxy = createCollectionProxy;
|
|
199
|
-
globalThis.__TS_RUNTIME__.resolveTargetProxy = resolveTargetProxy;
|
|
@@ -1,94 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Element state-inspection methods for `SingleElementProxy`.
|
|
3
|
-
*
|
|
4
|
-
* Thin delegations to the bound `PlatformDriverBridge`. No platform branching here.
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import type { ScopedSelector } from '@testspectra/matchers';
|
|
8
|
-
|
|
9
|
-
export function createElementState(selector: string | ScopedSelector, index: number | null): Record<string, any> {
|
|
10
|
-
const driver = () => globalThis.__TS_RUNTIME__.activeDriver!;
|
|
11
|
-
const selectorText = typeof selector === 'string' ? selector : selector.selector;
|
|
12
|
-
|
|
13
|
-
async function getText(): Promise<string> {
|
|
14
|
-
return await driver().getText(selector, index);
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
async function getValue(): Promise<string> {
|
|
18
|
-
return await driver().getValue(selector, index);
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
async function isDisplayed(): Promise<boolean> {
|
|
22
|
-
return await driver().isDisplayed(selector, index);
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
async function isVisible(): Promise<boolean> {
|
|
26
|
-
return await isDisplayed();
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
async function isExisting(): Promise<boolean> {
|
|
30
|
-
return await driver().isExisting(selector, index);
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
async function isEnabled(): Promise<boolean> {
|
|
34
|
-
return await driver().isEnabled(selector, index);
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
async function isSelected(): Promise<boolean> {
|
|
38
|
-
return await driver().isSelected(selector, index);
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
async function isChecked(): Promise<boolean> {
|
|
42
|
-
return await isSelected();
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
async function isFocused(): Promise<boolean> {
|
|
46
|
-
return await driver().isFocused(selector, index);
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
async function getAttribute(name: string): Promise<string | null> {
|
|
50
|
-
return await driver().getAttribute(selector, name, index);
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
async function getCSSProperty(name: string): Promise<{ value: string }> {
|
|
54
|
-
return await driver().getCSSProperty(selector, name, index);
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
async function waitForElement(timeoutMs?: number): Promise<boolean> {
|
|
58
|
-
const waitTimeout = timeoutMs ?? globalThis.__TS_RUNTIME__.getImplicitWaitMs();
|
|
59
|
-
const ok = await globalThis.__TS_RUNTIME__.pollCondition(
|
|
60
|
-
async () => driver().isExisting(selector, index),
|
|
61
|
-
waitTimeout,
|
|
62
|
-
);
|
|
63
|
-
if (ok) return true;
|
|
64
|
-
throw new Error('Element not found: ' + JSON.stringify(selectorText));
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
async function waitForDisplayed(opts: { timeout?: number } = {}): Promise<boolean> {
|
|
68
|
-
const timeout = opts.timeout || 5000;
|
|
69
|
-
const start = Date.now();
|
|
70
|
-
while (Date.now() - start < timeout) {
|
|
71
|
-
if (await driver().isDisplayed(selector, index)) return true;
|
|
72
|
-
await new Promise((r) => setTimeout(r, 20));
|
|
73
|
-
}
|
|
74
|
-
throw new Error(`Element ${selectorText} not displayed after ${timeout}ms`);
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
return {
|
|
78
|
-
getText,
|
|
79
|
-
getValue,
|
|
80
|
-
isDisplayed,
|
|
81
|
-
isVisible,
|
|
82
|
-
isExisting,
|
|
83
|
-
isEnabled,
|
|
84
|
-
isSelected,
|
|
85
|
-
isChecked,
|
|
86
|
-
isFocused,
|
|
87
|
-
getAttribute,
|
|
88
|
-
getCSSProperty,
|
|
89
|
-
waitForElement,
|
|
90
|
-
waitForDisplayed,
|
|
91
|
-
};
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
globalThis.__TS_RUNTIME__.createElementState = createElementState;
|
package/src/runtime/spectra.ts
DELETED
|
@@ -1,110 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Builds the global `Spectra` automation object.
|
|
3
|
-
*
|
|
4
|
-
* All static actions delegate to the bound `PlatformDriverBridge` (browser/navigation/gestures/
|
|
5
|
-
* network) or to element proxies (element actions). No platform branching here.
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
import type {
|
|
9
|
-
ClickOptions,
|
|
10
|
-
ElementTarget,
|
|
11
|
-
KeyOption,
|
|
12
|
-
LongPressOptions,
|
|
13
|
-
MockInterceptHandle,
|
|
14
|
-
ScrollOptions,
|
|
15
|
-
SpectraStatic,
|
|
16
|
-
SwipeOptions,
|
|
17
|
-
TypeOptions,
|
|
18
|
-
} from '@testspectra/matchers';
|
|
19
|
-
|
|
20
|
-
export function buildSpectra(): SpectraStatic {
|
|
21
|
-
const driver = () => globalThis.__TS_RUNTIME__.activeDriver!;
|
|
22
|
-
|
|
23
|
-
return {
|
|
24
|
-
get: (target: ElementTarget) => globalThis.__TS_RUNTIME__.resolveTargetProxy!(target),
|
|
25
|
-
getAll: (selector: string) => globalThis.__TS_RUNTIME__.createCollectionProxy!(selector),
|
|
26
|
-
navigate: (url: string) => driver().navigate(url),
|
|
27
|
-
back: () => driver().back(),
|
|
28
|
-
forward: () => driver().forward(),
|
|
29
|
-
refresh: () => driver().refresh(),
|
|
30
|
-
setViewport: (width: number, height: number) => driver().setViewport(width, height),
|
|
31
|
-
wait: (ms: number) => driver().pause(ms),
|
|
32
|
-
click: async (target: ElementTarget, _textOrOptions?: string | ClickOptions) => {
|
|
33
|
-
const el = globalThis.__TS_RUNTIME__.resolveTargetProxy!(target);
|
|
34
|
-
await el.click();
|
|
35
|
-
},
|
|
36
|
-
doubleClick: async (target: ElementTarget) => {
|
|
37
|
-
const el = globalThis.__TS_RUNTIME__.resolveTargetProxy!(target);
|
|
38
|
-
await el.doubleClick();
|
|
39
|
-
},
|
|
40
|
-
rightClick: async (target: ElementTarget) => {
|
|
41
|
-
const el = globalThis.__TS_RUNTIME__.resolveTargetProxy!(target);
|
|
42
|
-
await el.rightClick();
|
|
43
|
-
},
|
|
44
|
-
type: async (target: ElementTarget, text: string, options?: TypeOptions) => {
|
|
45
|
-
const el = globalThis.__TS_RUNTIME__.resolveTargetProxy!(target);
|
|
46
|
-
await el.type(text, options);
|
|
47
|
-
},
|
|
48
|
-
clear: async (target: ElementTarget) => {
|
|
49
|
-
const el = globalThis.__TS_RUNTIME__.resolveTargetProxy!(target);
|
|
50
|
-
await el.clear();
|
|
51
|
-
},
|
|
52
|
-
select: async (target: ElementTarget, option: string) => {
|
|
53
|
-
const el = globalThis.__TS_RUNTIME__.resolveTargetProxy!(target);
|
|
54
|
-
await el.select(option);
|
|
55
|
-
},
|
|
56
|
-
hover: async (target: ElementTarget) => {
|
|
57
|
-
const el = globalThis.__TS_RUNTIME__.resolveTargetProxy!(target);
|
|
58
|
-
await el.hover();
|
|
59
|
-
},
|
|
60
|
-
focus: async (target: ElementTarget) => {
|
|
61
|
-
const el = globalThis.__TS_RUNTIME__.resolveTargetProxy!(target);
|
|
62
|
-
await el.focus();
|
|
63
|
-
},
|
|
64
|
-
dragDrop: async (source: ElementTarget, destination: ElementTarget) => {
|
|
65
|
-
const srcEl = globalThis.__TS_RUNTIME__.resolveTargetProxy!(source);
|
|
66
|
-
await srcEl.dragDrop(destination);
|
|
67
|
-
},
|
|
68
|
-
scrollIntoView: async (target: ElementTarget) => {
|
|
69
|
-
const el = globalThis.__TS_RUNTIME__.resolveTargetProxy!(target);
|
|
70
|
-
await el.scrollIntoView();
|
|
71
|
-
},
|
|
72
|
-
scroll: async (options?: ScrollOptions) => {
|
|
73
|
-
await driver().scroll(options);
|
|
74
|
-
},
|
|
75
|
-
swipe: async (options: SwipeOptions) => {
|
|
76
|
-
await driver().swipe(options);
|
|
77
|
-
},
|
|
78
|
-
longPress: async (target: ElementTarget, options?: LongPressOptions | number) => {
|
|
79
|
-
const el = globalThis.__TS_RUNTIME__.resolveTargetProxy!(target);
|
|
80
|
-
await el.longPress(options);
|
|
81
|
-
},
|
|
82
|
-
pressKey: async (key: KeyOption | string) => {
|
|
83
|
-
await driver().pressKey(key);
|
|
84
|
-
},
|
|
85
|
-
grantPermission: async (name: string) => {
|
|
86
|
-
await driver().grantPermission(name);
|
|
87
|
-
},
|
|
88
|
-
waitForElement: async (target: ElementTarget, timeoutMs?: number) => {
|
|
89
|
-
const el = globalThis.__TS_RUNTIME__.resolveTargetProxy!(target);
|
|
90
|
-
await el.waitForElement(timeoutMs);
|
|
91
|
-
},
|
|
92
|
-
intercept: async (
|
|
93
|
-
patternOrOptions: any,
|
|
94
|
-
maybeMethodOrHandler?: any,
|
|
95
|
-
maybeFixture?: any,
|
|
96
|
-
maybeOptions?: any,
|
|
97
|
-
): Promise<MockInterceptHandle> => {
|
|
98
|
-
return await driver().intercept(patternOrOptions, maybeMethodOrHandler, maybeFixture, maybeOptions);
|
|
99
|
-
},
|
|
100
|
-
clearMocks: () => {
|
|
101
|
-
driver().clearMocks();
|
|
102
|
-
},
|
|
103
|
-
get browser() {
|
|
104
|
-
return driver();
|
|
105
|
-
},
|
|
106
|
-
env: (globalThis.__TS_RUNTIME__.config.environmentVariables || {}) as SpectraEnv,
|
|
107
|
-
};
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
globalThis.__TS_RUNTIME__.buildSpectra = buildSpectra;
|
|
Binary file
|