@oracle/oraclejet-dom-driver 19.0.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.
@@ -0,0 +1,219 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ var UNSAFE_Driver = require('@oracle/oraclejet-testing/UNSAFE_Driver');
6
+ var defaultUserEvent = require('@testing-library/user-event');
7
+
8
+ function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
9
+
10
+ var defaultUserEvent__default = /*#__PURE__*/_interopDefaultLegacy(defaultUserEvent);
11
+
12
+ const userEvent = defaultUserEvent__default["default"].setup();
13
+ const modifierKeys = {
14
+ SHIFT: '{Shift}',
15
+ CONTROL: '{Control}',
16
+ // jest always runs in linux-like environment, so CONTROL_COMMAND is always 'Control'
17
+ CONTROL_COMMAND: '{Control}',
18
+ ALT: '{Alt}'
19
+ };
20
+ const keyMap = {
21
+ ...modifierKeys,
22
+ BACKSPACE: '{Backspace}',
23
+ TAB: '{Tab}',
24
+ ENTER: '{Enter}',
25
+ ESCAPE: '{Escape}',
26
+ PAGE_UP: '{PageUp}',
27
+ PAGE_DOWN: '{PageDown}',
28
+ END: '{End}',
29
+ HOME: '{Home}',
30
+ ARROW_LEFT: '{ArrowLeft}',
31
+ ARROW_UP: '{ArrowUp}',
32
+ ARROW_RIGHT: '{ArrowRight}',
33
+ ARROW_DOWN: '{ArrowDown}',
34
+ DELETE: '{Delete}',
35
+ F1: '{F1}',
36
+ F2: '{F2}',
37
+ F3: '{F3}',
38
+ F4: '{F4}',
39
+ F5: '{F5}',
40
+ F6: '{F6}',
41
+ F7: '{F7}',
42
+ F8: '{F8}',
43
+ F9: '{F9}',
44
+ F10: '{F10}',
45
+ F11: '{F11}',
46
+ F12: '{F12}'
47
+ };
48
+ function getMappedKey(key) {
49
+ if (typeof key === 'object') {
50
+ return keyMap[key.key];
51
+ }
52
+ return key;
53
+ }
54
+ /**
55
+ * Get an array of keys (chord) representing the given parameters, substituting modifier keys
56
+ * with their equivalent user-event values.
57
+ * Ex. "{CONTROL},a" -> "{CONTROL>}a{/CONTROL}"
58
+ * @param values The values from which to create a chord
59
+ * @returns The array of keys
60
+ */
61
+ function getChord(values) {
62
+ const text = values.map(getMappedKey);
63
+ const modifierValues = Object.values(modifierKeys);
64
+ const modifierValueRegEx = new RegExp(`\\{(${modifierValues.map((m) => m.replace(/[{}]/g, '')).join('|')})>\\}`);
65
+ const chord = text.map((v) =>
66
+ // {ALT} => {ALT>}
67
+ modifierValues.includes(v) ? `${v.replace(/}$/, '>}')}` : v);
68
+ // add modifier release values
69
+ return chord.reduceRight((accum, v) => {
70
+ const match = v.match(modifierValueRegEx);
71
+ if (match) {
72
+ accum.push(`{/${match[1]}}`);
73
+ }
74
+ return accum;
75
+ }, chord);
76
+ }
77
+ /**
78
+ * A DOM-based TestDriver. This works in environments where the DOM is directly
79
+ * available, such as Jest or Karma.
80
+ */
81
+ class DomDriverImpl extends UNSAFE_Driver.TestDriverBase {
82
+ constructor() {
83
+ super(...arguments);
84
+ this._waitForElement = async (locator, parent) => {
85
+ try {
86
+ const el = await this.waitFor(() => parent.querySelector(locator.css), {
87
+ timeout: UNSAFE_Driver.getTimeouts().elementExistsTimeout
88
+ });
89
+ if (el instanceof HTMLElement) {
90
+ return Promise.resolve(wrapElement(el, this._waitForElement, this._waitForElements));
91
+ }
92
+ else {
93
+ throw Error(`"${JSON.stringify(locator)} did not locate an HTMLElement: ${el?.tagName}`);
94
+ }
95
+ }
96
+ catch {
97
+ throw Error(`No element matching query "${JSON.stringify(locator)}"`);
98
+ }
99
+ };
100
+ this._waitForElements = async (locator, parent) => {
101
+ let matches;
102
+ try {
103
+ // loop to find at least 1 match
104
+ matches = await this.waitFor(() => {
105
+ const all = parent.querySelectorAll(locator.css);
106
+ if (all.length) {
107
+ return all;
108
+ }
109
+ return;
110
+ }, {
111
+ timeout: UNSAFE_Driver.getTimeouts().elementExistsTimeout
112
+ });
113
+ }
114
+ catch {
115
+ return [];
116
+ }
117
+ return Promise.resolve(Array.from(matches || []).map((m) => {
118
+ if (m instanceof HTMLElement) {
119
+ return wrapElement(m, this._waitForElement, this._waitForElements);
120
+ }
121
+ throw Error(`"${JSON.stringify(locator)} did not locate an HTMLElement: ${m.tagName}`);
122
+ }));
123
+ };
124
+ }
125
+ executeScript(script, ...args) {
126
+ if (typeof script === 'string') {
127
+ const func = new Function(`
128
+ function execute() {
129
+ ${script}
130
+ }
131
+ return execute.call(undefined, ${args.map(JSON.stringify).join(', ')});
132
+ `);
133
+ return this._waitOnFunction(func);
134
+ }
135
+ return this._waitOnFunction(() => script.apply(null, args));
136
+ }
137
+ _waitOnFunction(func) {
138
+ const promises = [
139
+ new Promise((accept, reject) => {
140
+ try {
141
+ const retValue = func();
142
+ accept(retValue);
143
+ }
144
+ catch (ex) {
145
+ reject(ex);
146
+ }
147
+ })
148
+ ];
149
+ const start = performance.now();
150
+ const { scriptTimeout } = UNSAFE_Driver.getTimeouts();
151
+ if (scriptTimeout) {
152
+ promises.push(new Promise((_, reject) => {
153
+ setTimeout(() => {
154
+ const now = performance.now();
155
+ const elapsed = Math.round(now - start);
156
+ reject(new Error(`script execution timed out after ${elapsed}ms`));
157
+ }, scriptTimeout);
158
+ }));
159
+ }
160
+ return Promise.race(promises);
161
+ }
162
+ async waitForElement(locator) {
163
+ return this._waitForElement(locator, document);
164
+ }
165
+ waitForElements(locator) {
166
+ return this._waitForElements(locator, document);
167
+ }
168
+ /**
169
+ * Get a TestElement for the given HTMLElement
170
+ * @param from The HTMLElement
171
+ * @returns A TestElement
172
+ */
173
+ getTestElement(from) {
174
+ return wrapElement(from, this._waitForElement, this._waitForElements);
175
+ }
176
+ async click(element, options = {}) {
177
+ const chord = getChord(options.modifiers || []);
178
+ // send the first half of the chord (key-down values), then click()
179
+ chord.length && (await userEvent.keyboard(chord.slice(0, chord.length / 2).join('')));
180
+ await userEvent.click(this.unwrapElement(element));
181
+ // send the second half of the chord (key-up values)
182
+ chord.length && (await userEvent.keyboard(chord.slice(chord.length / 2).join('')));
183
+ }
184
+ async sendKeys(element, ...text) {
185
+ const el = this.unwrapElement(element);
186
+ // ensure focus if blurred (re-focusing will clear out selection)
187
+ if (document.activeElement !== el) {
188
+ el.focus();
189
+ }
190
+ await userEvent.keyboard(getChord(text).join(''));
191
+ }
192
+ unwrapElement(element) {
193
+ return element._el;
194
+ }
195
+ }
196
+ const DomDriver = new DomDriverImpl();
197
+ function wrapElement(element, waitForElement, waitForElements) {
198
+ return new TestElementImpl(element, waitForElement, waitForElements);
199
+ }
200
+ class TestElementImpl {
201
+ constructor(element, waitForElement, waitForElements) {
202
+ this._el = element;
203
+ this._waitForElement = waitForElement;
204
+ this._waitForElements = waitForElements;
205
+ }
206
+ waitForElement(locator) {
207
+ return this._waitForElement(locator, this._el);
208
+ }
209
+ waitForElements(locator) {
210
+ return this._waitForElements(locator, this._el);
211
+ }
212
+ getAttribute(attrName) {
213
+ return Promise.resolve(this._el.getAttribute(attrName));
214
+ }
215
+ }
216
+
217
+ exports.DomDriver = DomDriver;
218
+ exports.keyMap = keyMap;
219
+ //# sourceMappingURL=DomDriver.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DomDriver.cjs","sources":["../../src/UNSAFE_DomDriver/DomDriver.ts"],"sourcesContent":["import {\n type KeyType,\n type TestElement,\n type ClickOptions,\n TestDriverBase,\n getTimeouts\n} from '@oracle/oraclejet-testing/UNSAFE_Driver';\nimport { ElementLocator } from '@oracle/oraclejet-testing/UNSAFE_Locators';\nimport defaultUserEvent from '@testing-library/user-event';\n\nconst userEvent = defaultUserEvent.setup();\n\nconst modifierKeys = {\n SHIFT: '{Shift}',\n CONTROL: '{Control}',\n // jest always runs in linux-like environment, so CONTROL_COMMAND is always 'Control'\n CONTROL_COMMAND: '{Control}',\n ALT: '{Alt}'\n};\n\ntype WaitForElementType = (\n locator: ElementLocator,\n parent: Document | Element\n) => Promise<TestElement>;\n\ntype WaitForElementsType = (\n locator: ElementLocator,\n parent: Document | Element\n) => Promise<TestElement[]>;\n\nexport const keyMap: { [key: string]: string } = {\n ...modifierKeys,\n BACKSPACE: '{Backspace}',\n TAB: '{Tab}',\n ENTER: '{Enter}',\n ESCAPE: '{Escape}',\n PAGE_UP: '{PageUp}',\n PAGE_DOWN: '{PageDown}',\n END: '{End}',\n HOME: '{Home}',\n ARROW_LEFT: '{ArrowLeft}',\n ARROW_UP: '{ArrowUp}',\n ARROW_RIGHT: '{ArrowRight}',\n ARROW_DOWN: '{ArrowDown}',\n DELETE: '{Delete}',\n\n F1: '{F1}',\n F2: '{F2}',\n F3: '{F3}',\n F4: '{F4}',\n F5: '{F5}',\n F6: '{F6}',\n F7: '{F7}',\n F8: '{F8}',\n F9: '{F9}',\n F10: '{F10}',\n F11: '{F11}',\n F12: '{F12}'\n};\n\nfunction getMappedKey(key: string | KeyType) {\n if (typeof key === 'object') {\n return keyMap[key.key];\n }\n return key;\n}\n\n/**\n * Get an array of keys (chord) representing the given parameters, substituting modifier keys\n * with their equivalent user-event values.\n * Ex. \"{CONTROL},a\" -> \"{CONTROL>}a{/CONTROL}\"\n * @param values The values from which to create a chord\n * @returns The array of keys\n */\nfunction getChord(values: (string | KeyType)[]) {\n const text = values.map(getMappedKey);\n const modifierValues = Object.values(modifierKeys);\n const modifierValueRegEx = new RegExp(\n `\\\\{(${modifierValues.map((m) => m.replace(/[{}]/g, '')).join('|')})>\\\\}`\n );\n const chord = text.map((v) =>\n // {ALT} => {ALT>}\n modifierValues.includes(v) ? `${v.replace(/}$/, '>}')}` : v\n );\n // add modifier release values\n return chord.reduceRight((accum, v) => {\n const match = v.match(modifierValueRegEx);\n if (match) {\n accum.push(`{/${match[1]}}`);\n }\n return accum;\n }, chord);\n}\n\n/**\n * A DOM-based TestDriver. This works in environments where the DOM is directly\n * available, such as Jest or Karma.\n */\nclass DomDriverImpl extends TestDriverBase {\n executeScript<T>(script: string | ((...args: any) => T), ...args: any) {\n if (typeof script === 'string') {\n const func = new Function(`\n function execute() {\n ${script}\n }\n return execute.call(undefined, ${args.map(JSON.stringify).join(', ')});\n `) as () => T;\n return this._waitOnFunction<T>(func);\n }\n return this._waitOnFunction<T>(() => script.apply(null, args));\n }\n\n private _waitOnFunction<T>(func: () => T) {\n const promises = [\n new Promise<T>((accept, reject) => {\n try {\n const retValue = func();\n accept(retValue);\n } catch (ex) {\n reject(ex);\n }\n })\n ];\n const start = performance.now();\n const { scriptTimeout } = getTimeouts();\n if (scriptTimeout) {\n promises.push(\n new Promise((_, reject) => {\n setTimeout(() => {\n const now = performance.now();\n const elapsed = Math.round(now - start);\n reject(new Error(`script execution timed out after ${elapsed}ms`));\n }, scriptTimeout);\n })\n );\n }\n return Promise.race(promises);\n }\n\n async waitForElement(locator: ElementLocator) {\n return this._waitForElement(locator, document);\n }\n\n waitForElements(locator: ElementLocator) {\n return this._waitForElements(locator, document);\n }\n\n private _waitForElement = async (locator: ElementLocator, parent: Document | Element) => {\n try {\n const el = await this.waitFor<Element | null>(() => parent.querySelector(locator.css), {\n timeout: getTimeouts().elementExistsTimeout\n });\n if (el instanceof HTMLElement) {\n return Promise.resolve(wrapElement(el, this._waitForElement, this._waitForElements));\n } else {\n throw Error(`\"${JSON.stringify(locator)} did not locate an HTMLElement: ${el?.tagName}`);\n }\n } catch {\n throw Error(`No element matching query \"${JSON.stringify(locator)}\"`);\n }\n };\n\n private _waitForElements = async (locator: ElementLocator, parent: Document | Element) => {\n let matches: NodeListOf<Element> | undefined;\n try {\n // loop to find at least 1 match\n matches = await this.waitFor<NodeListOf<Element> | undefined>(\n () => {\n const all = parent.querySelectorAll(locator.css);\n if (all.length) {\n return all;\n }\n return;\n },\n {\n timeout: getTimeouts().elementExistsTimeout\n }\n );\n } catch {\n return [];\n }\n return Promise.resolve(\n Array.from(matches || []).map((m) => {\n if (m instanceof HTMLElement) {\n return wrapElement(m, this._waitForElement, this._waitForElements);\n }\n throw Error(`\"${JSON.stringify(locator)} did not locate an HTMLElement: ${m.tagName}`);\n })\n );\n };\n\n /**\n * Get a TestElement for the given HTMLElement\n * @param from The HTMLElement\n * @returns A TestElement\n */\n getTestElement(from: HTMLElement) {\n return wrapElement(from, this._waitForElement, this._waitForElements);\n }\n\n async click(element: TestElement, options: ClickOptions = {}) {\n const chord = getChord(options.modifiers || []);\n // send the first half of the chord (key-down values), then click()\n chord.length && (await userEvent.keyboard(chord.slice(0, chord.length / 2).join('')));\n await userEvent.click(this.unwrapElement(element));\n // send the second half of the chord (key-up values)\n chord.length && (await userEvent.keyboard(chord.slice(chord.length / 2).join('')));\n }\n\n async sendKeys(element: TestElement, ...text: (string | KeyType)[]) {\n const el = this.unwrapElement(element);\n // ensure focus if blurred (re-focusing will clear out selection)\n if (document.activeElement !== el) {\n el.focus();\n }\n\n await userEvent.keyboard(getChord(text).join(''));\n }\n\n unwrapElement<T = HTMLElement>(element: TestElement): T {\n return (element as TestElementImpl)._el as T;\n }\n}\n\nexport const DomDriver = new DomDriverImpl();\n\nfunction wrapElement(\n element: HTMLElement,\n waitForElement: WaitForElementType,\n waitForElements: WaitForElementsType\n) {\n return new TestElementImpl(element, waitForElement, waitForElements);\n}\n\nclass TestElementImpl implements TestElement {\n _el: HTMLElement;\n _waitForElement: WaitForElementType;\n _waitForElements: WaitForElementsType;\n\n constructor(\n element: HTMLElement,\n waitForElement: WaitForElementType,\n waitForElements: WaitForElementsType\n ) {\n this._el = element;\n this._waitForElement = waitForElement;\n this._waitForElements = waitForElements;\n }\n waitForElement(locator: ElementLocator): Promise<TestElement> {\n return this._waitForElement(locator, this._el);\n }\n waitForElements(locator: ElementLocator): Promise<TestElement[]> {\n return this._waitForElements(locator, this._el);\n }\n getAttribute(attrName: string): Promise<string | null> {\n return Promise.resolve(this._el.getAttribute(attrName));\n }\n}\n"],"names":["defaultUserEvent","TestDriverBase","getTimeouts"],"mappings":"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"}
@@ -0,0 +1,39 @@
1
+ import { type KeyType, type TestElement, type ClickOptions, TestDriverBase } from '@oracle/oraclejet-testing/UNSAFE_Driver';
2
+ import { ElementLocator } from '@oracle/oraclejet-testing/UNSAFE_Locators';
3
+ type WaitForElementType = (locator: ElementLocator, parent: Document | Element) => Promise<TestElement>;
4
+ type WaitForElementsType = (locator: ElementLocator, parent: Document | Element) => Promise<TestElement[]>;
5
+ export declare const keyMap: {
6
+ [key: string]: string;
7
+ };
8
+ /**
9
+ * A DOM-based TestDriver. This works in environments where the DOM is directly
10
+ * available, such as Jest or Karma.
11
+ */
12
+ declare class DomDriverImpl extends TestDriverBase {
13
+ executeScript<T>(script: string | ((...args: any) => T), ...args: any): Promise<Awaited<T>>;
14
+ private _waitOnFunction;
15
+ waitForElement(locator: ElementLocator): Promise<TestElementImpl>;
16
+ waitForElements(locator: ElementLocator): Promise<TestElementImpl[]>;
17
+ private _waitForElement;
18
+ private _waitForElements;
19
+ /**
20
+ * Get a TestElement for the given HTMLElement
21
+ * @param from The HTMLElement
22
+ * @returns A TestElement
23
+ */
24
+ getTestElement(from: HTMLElement): TestElementImpl;
25
+ click(element: TestElement, options?: ClickOptions): Promise<void>;
26
+ sendKeys(element: TestElement, ...text: (string | KeyType)[]): Promise<void>;
27
+ unwrapElement<T = HTMLElement>(element: TestElement): T;
28
+ }
29
+ export declare const DomDriver: DomDriverImpl;
30
+ declare class TestElementImpl implements TestElement {
31
+ _el: HTMLElement;
32
+ _waitForElement: WaitForElementType;
33
+ _waitForElements: WaitForElementsType;
34
+ constructor(element: HTMLElement, waitForElement: WaitForElementType, waitForElements: WaitForElementsType);
35
+ waitForElement(locator: ElementLocator): Promise<TestElement>;
36
+ waitForElements(locator: ElementLocator): Promise<TestElement[]>;
37
+ getAttribute(attrName: string): Promise<string | null>;
38
+ }
39
+ export {};
@@ -0,0 +1,210 @@
1
+ import { TestDriverBase, getTimeouts } from '@oracle/oraclejet-testing/UNSAFE_Driver';
2
+ import defaultUserEvent from '@testing-library/user-event';
3
+
4
+ const userEvent = defaultUserEvent.setup();
5
+ const modifierKeys = {
6
+ SHIFT: '{Shift}',
7
+ CONTROL: '{Control}',
8
+ // jest always runs in linux-like environment, so CONTROL_COMMAND is always 'Control'
9
+ CONTROL_COMMAND: '{Control}',
10
+ ALT: '{Alt}'
11
+ };
12
+ const keyMap = {
13
+ ...modifierKeys,
14
+ BACKSPACE: '{Backspace}',
15
+ TAB: '{Tab}',
16
+ ENTER: '{Enter}',
17
+ ESCAPE: '{Escape}',
18
+ PAGE_UP: '{PageUp}',
19
+ PAGE_DOWN: '{PageDown}',
20
+ END: '{End}',
21
+ HOME: '{Home}',
22
+ ARROW_LEFT: '{ArrowLeft}',
23
+ ARROW_UP: '{ArrowUp}',
24
+ ARROW_RIGHT: '{ArrowRight}',
25
+ ARROW_DOWN: '{ArrowDown}',
26
+ DELETE: '{Delete}',
27
+ F1: '{F1}',
28
+ F2: '{F2}',
29
+ F3: '{F3}',
30
+ F4: '{F4}',
31
+ F5: '{F5}',
32
+ F6: '{F6}',
33
+ F7: '{F7}',
34
+ F8: '{F8}',
35
+ F9: '{F9}',
36
+ F10: '{F10}',
37
+ F11: '{F11}',
38
+ F12: '{F12}'
39
+ };
40
+ function getMappedKey(key) {
41
+ if (typeof key === 'object') {
42
+ return keyMap[key.key];
43
+ }
44
+ return key;
45
+ }
46
+ /**
47
+ * Get an array of keys (chord) representing the given parameters, substituting modifier keys
48
+ * with their equivalent user-event values.
49
+ * Ex. "{CONTROL},a" -> "{CONTROL>}a{/CONTROL}"
50
+ * @param values The values from which to create a chord
51
+ * @returns The array of keys
52
+ */
53
+ function getChord(values) {
54
+ const text = values.map(getMappedKey);
55
+ const modifierValues = Object.values(modifierKeys);
56
+ const modifierValueRegEx = new RegExp(`\\{(${modifierValues.map((m) => m.replace(/[{}]/g, '')).join('|')})>\\}`);
57
+ const chord = text.map((v) =>
58
+ // {ALT} => {ALT>}
59
+ modifierValues.includes(v) ? `${v.replace(/}$/, '>}')}` : v);
60
+ // add modifier release values
61
+ return chord.reduceRight((accum, v) => {
62
+ const match = v.match(modifierValueRegEx);
63
+ if (match) {
64
+ accum.push(`{/${match[1]}}`);
65
+ }
66
+ return accum;
67
+ }, chord);
68
+ }
69
+ /**
70
+ * A DOM-based TestDriver. This works in environments where the DOM is directly
71
+ * available, such as Jest or Karma.
72
+ */
73
+ class DomDriverImpl extends TestDriverBase {
74
+ constructor() {
75
+ super(...arguments);
76
+ this._waitForElement = async (locator, parent) => {
77
+ try {
78
+ const el = await this.waitFor(() => parent.querySelector(locator.css), {
79
+ timeout: getTimeouts().elementExistsTimeout
80
+ });
81
+ if (el instanceof HTMLElement) {
82
+ return Promise.resolve(wrapElement(el, this._waitForElement, this._waitForElements));
83
+ }
84
+ else {
85
+ throw Error(`"${JSON.stringify(locator)} did not locate an HTMLElement: ${el?.tagName}`);
86
+ }
87
+ }
88
+ catch {
89
+ throw Error(`No element matching query "${JSON.stringify(locator)}"`);
90
+ }
91
+ };
92
+ this._waitForElements = async (locator, parent) => {
93
+ let matches;
94
+ try {
95
+ // loop to find at least 1 match
96
+ matches = await this.waitFor(() => {
97
+ const all = parent.querySelectorAll(locator.css);
98
+ if (all.length) {
99
+ return all;
100
+ }
101
+ return;
102
+ }, {
103
+ timeout: getTimeouts().elementExistsTimeout
104
+ });
105
+ }
106
+ catch {
107
+ return [];
108
+ }
109
+ return Promise.resolve(Array.from(matches || []).map((m) => {
110
+ if (m instanceof HTMLElement) {
111
+ return wrapElement(m, this._waitForElement, this._waitForElements);
112
+ }
113
+ throw Error(`"${JSON.stringify(locator)} did not locate an HTMLElement: ${m.tagName}`);
114
+ }));
115
+ };
116
+ }
117
+ executeScript(script, ...args) {
118
+ if (typeof script === 'string') {
119
+ const func = new Function(`
120
+ function execute() {
121
+ ${script}
122
+ }
123
+ return execute.call(undefined, ${args.map(JSON.stringify).join(', ')});
124
+ `);
125
+ return this._waitOnFunction(func);
126
+ }
127
+ return this._waitOnFunction(() => script.apply(null, args));
128
+ }
129
+ _waitOnFunction(func) {
130
+ const promises = [
131
+ new Promise((accept, reject) => {
132
+ try {
133
+ const retValue = func();
134
+ accept(retValue);
135
+ }
136
+ catch (ex) {
137
+ reject(ex);
138
+ }
139
+ })
140
+ ];
141
+ const start = performance.now();
142
+ const { scriptTimeout } = getTimeouts();
143
+ if (scriptTimeout) {
144
+ promises.push(new Promise((_, reject) => {
145
+ setTimeout(() => {
146
+ const now = performance.now();
147
+ const elapsed = Math.round(now - start);
148
+ reject(new Error(`script execution timed out after ${elapsed}ms`));
149
+ }, scriptTimeout);
150
+ }));
151
+ }
152
+ return Promise.race(promises);
153
+ }
154
+ async waitForElement(locator) {
155
+ return this._waitForElement(locator, document);
156
+ }
157
+ waitForElements(locator) {
158
+ return this._waitForElements(locator, document);
159
+ }
160
+ /**
161
+ * Get a TestElement for the given HTMLElement
162
+ * @param from The HTMLElement
163
+ * @returns A TestElement
164
+ */
165
+ getTestElement(from) {
166
+ return wrapElement(from, this._waitForElement, this._waitForElements);
167
+ }
168
+ async click(element, options = {}) {
169
+ const chord = getChord(options.modifiers || []);
170
+ // send the first half of the chord (key-down values), then click()
171
+ chord.length && (await userEvent.keyboard(chord.slice(0, chord.length / 2).join('')));
172
+ await userEvent.click(this.unwrapElement(element));
173
+ // send the second half of the chord (key-up values)
174
+ chord.length && (await userEvent.keyboard(chord.slice(chord.length / 2).join('')));
175
+ }
176
+ async sendKeys(element, ...text) {
177
+ const el = this.unwrapElement(element);
178
+ // ensure focus if blurred (re-focusing will clear out selection)
179
+ if (document.activeElement !== el) {
180
+ el.focus();
181
+ }
182
+ await userEvent.keyboard(getChord(text).join(''));
183
+ }
184
+ unwrapElement(element) {
185
+ return element._el;
186
+ }
187
+ }
188
+ const DomDriver = new DomDriverImpl();
189
+ function wrapElement(element, waitForElement, waitForElements) {
190
+ return new TestElementImpl(element, waitForElement, waitForElements);
191
+ }
192
+ class TestElementImpl {
193
+ constructor(element, waitForElement, waitForElements) {
194
+ this._el = element;
195
+ this._waitForElement = waitForElement;
196
+ this._waitForElements = waitForElements;
197
+ }
198
+ waitForElement(locator) {
199
+ return this._waitForElement(locator, this._el);
200
+ }
201
+ waitForElements(locator) {
202
+ return this._waitForElements(locator, this._el);
203
+ }
204
+ getAttribute(attrName) {
205
+ return Promise.resolve(this._el.getAttribute(attrName));
206
+ }
207
+ }
208
+
209
+ export { DomDriver, keyMap };
210
+ //# sourceMappingURL=DomDriver.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DomDriver.mjs","sources":["../../src/UNSAFE_DomDriver/DomDriver.ts"],"sourcesContent":["import {\n type KeyType,\n type TestElement,\n type ClickOptions,\n TestDriverBase,\n getTimeouts\n} from '@oracle/oraclejet-testing/UNSAFE_Driver';\nimport { ElementLocator } from '@oracle/oraclejet-testing/UNSAFE_Locators';\nimport defaultUserEvent from '@testing-library/user-event';\n\nconst userEvent = defaultUserEvent.setup();\n\nconst modifierKeys = {\n SHIFT: '{Shift}',\n CONTROL: '{Control}',\n // jest always runs in linux-like environment, so CONTROL_COMMAND is always 'Control'\n CONTROL_COMMAND: '{Control}',\n ALT: '{Alt}'\n};\n\ntype WaitForElementType = (\n locator: ElementLocator,\n parent: Document | Element\n) => Promise<TestElement>;\n\ntype WaitForElementsType = (\n locator: ElementLocator,\n parent: Document | Element\n) => Promise<TestElement[]>;\n\nexport const keyMap: { [key: string]: string } = {\n ...modifierKeys,\n BACKSPACE: '{Backspace}',\n TAB: '{Tab}',\n ENTER: '{Enter}',\n ESCAPE: '{Escape}',\n PAGE_UP: '{PageUp}',\n PAGE_DOWN: '{PageDown}',\n END: '{End}',\n HOME: '{Home}',\n ARROW_LEFT: '{ArrowLeft}',\n ARROW_UP: '{ArrowUp}',\n ARROW_RIGHT: '{ArrowRight}',\n ARROW_DOWN: '{ArrowDown}',\n DELETE: '{Delete}',\n\n F1: '{F1}',\n F2: '{F2}',\n F3: '{F3}',\n F4: '{F4}',\n F5: '{F5}',\n F6: '{F6}',\n F7: '{F7}',\n F8: '{F8}',\n F9: '{F9}',\n F10: '{F10}',\n F11: '{F11}',\n F12: '{F12}'\n};\n\nfunction getMappedKey(key: string | KeyType) {\n if (typeof key === 'object') {\n return keyMap[key.key];\n }\n return key;\n}\n\n/**\n * Get an array of keys (chord) representing the given parameters, substituting modifier keys\n * with their equivalent user-event values.\n * Ex. \"{CONTROL},a\" -> \"{CONTROL>}a{/CONTROL}\"\n * @param values The values from which to create a chord\n * @returns The array of keys\n */\nfunction getChord(values: (string | KeyType)[]) {\n const text = values.map(getMappedKey);\n const modifierValues = Object.values(modifierKeys);\n const modifierValueRegEx = new RegExp(\n `\\\\{(${modifierValues.map((m) => m.replace(/[{}]/g, '')).join('|')})>\\\\}`\n );\n const chord = text.map((v) =>\n // {ALT} => {ALT>}\n modifierValues.includes(v) ? `${v.replace(/}$/, '>}')}` : v\n );\n // add modifier release values\n return chord.reduceRight((accum, v) => {\n const match = v.match(modifierValueRegEx);\n if (match) {\n accum.push(`{/${match[1]}}`);\n }\n return accum;\n }, chord);\n}\n\n/**\n * A DOM-based TestDriver. This works in environments where the DOM is directly\n * available, such as Jest or Karma.\n */\nclass DomDriverImpl extends TestDriverBase {\n executeScript<T>(script: string | ((...args: any) => T), ...args: any) {\n if (typeof script === 'string') {\n const func = new Function(`\n function execute() {\n ${script}\n }\n return execute.call(undefined, ${args.map(JSON.stringify).join(', ')});\n `) as () => T;\n return this._waitOnFunction<T>(func);\n }\n return this._waitOnFunction<T>(() => script.apply(null, args));\n }\n\n private _waitOnFunction<T>(func: () => T) {\n const promises = [\n new Promise<T>((accept, reject) => {\n try {\n const retValue = func();\n accept(retValue);\n } catch (ex) {\n reject(ex);\n }\n })\n ];\n const start = performance.now();\n const { scriptTimeout } = getTimeouts();\n if (scriptTimeout) {\n promises.push(\n new Promise((_, reject) => {\n setTimeout(() => {\n const now = performance.now();\n const elapsed = Math.round(now - start);\n reject(new Error(`script execution timed out after ${elapsed}ms`));\n }, scriptTimeout);\n })\n );\n }\n return Promise.race(promises);\n }\n\n async waitForElement(locator: ElementLocator) {\n return this._waitForElement(locator, document);\n }\n\n waitForElements(locator: ElementLocator) {\n return this._waitForElements(locator, document);\n }\n\n private _waitForElement = async (locator: ElementLocator, parent: Document | Element) => {\n try {\n const el = await this.waitFor<Element | null>(() => parent.querySelector(locator.css), {\n timeout: getTimeouts().elementExistsTimeout\n });\n if (el instanceof HTMLElement) {\n return Promise.resolve(wrapElement(el, this._waitForElement, this._waitForElements));\n } else {\n throw Error(`\"${JSON.stringify(locator)} did not locate an HTMLElement: ${el?.tagName}`);\n }\n } catch {\n throw Error(`No element matching query \"${JSON.stringify(locator)}\"`);\n }\n };\n\n private _waitForElements = async (locator: ElementLocator, parent: Document | Element) => {\n let matches: NodeListOf<Element> | undefined;\n try {\n // loop to find at least 1 match\n matches = await this.waitFor<NodeListOf<Element> | undefined>(\n () => {\n const all = parent.querySelectorAll(locator.css);\n if (all.length) {\n return all;\n }\n return;\n },\n {\n timeout: getTimeouts().elementExistsTimeout\n }\n );\n } catch {\n return [];\n }\n return Promise.resolve(\n Array.from(matches || []).map((m) => {\n if (m instanceof HTMLElement) {\n return wrapElement(m, this._waitForElement, this._waitForElements);\n }\n throw Error(`\"${JSON.stringify(locator)} did not locate an HTMLElement: ${m.tagName}`);\n })\n );\n };\n\n /**\n * Get a TestElement for the given HTMLElement\n * @param from The HTMLElement\n * @returns A TestElement\n */\n getTestElement(from: HTMLElement) {\n return wrapElement(from, this._waitForElement, this._waitForElements);\n }\n\n async click(element: TestElement, options: ClickOptions = {}) {\n const chord = getChord(options.modifiers || []);\n // send the first half of the chord (key-down values), then click()\n chord.length && (await userEvent.keyboard(chord.slice(0, chord.length / 2).join('')));\n await userEvent.click(this.unwrapElement(element));\n // send the second half of the chord (key-up values)\n chord.length && (await userEvent.keyboard(chord.slice(chord.length / 2).join('')));\n }\n\n async sendKeys(element: TestElement, ...text: (string | KeyType)[]) {\n const el = this.unwrapElement(element);\n // ensure focus if blurred (re-focusing will clear out selection)\n if (document.activeElement !== el) {\n el.focus();\n }\n\n await userEvent.keyboard(getChord(text).join(''));\n }\n\n unwrapElement<T = HTMLElement>(element: TestElement): T {\n return (element as TestElementImpl)._el as T;\n }\n}\n\nexport const DomDriver = new DomDriverImpl();\n\nfunction wrapElement(\n element: HTMLElement,\n waitForElement: WaitForElementType,\n waitForElements: WaitForElementsType\n) {\n return new TestElementImpl(element, waitForElement, waitForElements);\n}\n\nclass TestElementImpl implements TestElement {\n _el: HTMLElement;\n _waitForElement: WaitForElementType;\n _waitForElements: WaitForElementsType;\n\n constructor(\n element: HTMLElement,\n waitForElement: WaitForElementType,\n waitForElements: WaitForElementsType\n ) {\n this._el = element;\n this._waitForElement = waitForElement;\n this._waitForElements = waitForElements;\n }\n waitForElement(locator: ElementLocator): Promise<TestElement> {\n return this._waitForElement(locator, this._el);\n }\n waitForElements(locator: ElementLocator): Promise<TestElement[]> {\n return this._waitForElements(locator, this._el);\n }\n getAttribute(attrName: string): Promise<string | null> {\n return Promise.resolve(this._el.getAttribute(attrName));\n }\n}\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ var DomDriver = require('./DomDriver.cjs');
6
+
7
+
8
+
9
+ exports.DomDriver = DomDriver.DomDriver;
10
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;"}
@@ -0,0 +1 @@
1
+ export { DomDriver } from './DomDriver';
@@ -0,0 +1,2 @@
1
+ export { DomDriver } from './DomDriver.mjs';
2
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":""}
package/package.json ADDED
@@ -0,0 +1,55 @@
1
+ {
2
+ "name": "@oracle/oraclejet-dom-driver",
3
+ "scripts": {
4
+ "build": "turbo run-build --filter=@oracle/oraclejet-dom-driver",
5
+ "check-types": "turbo run-check-types --filter=@oracle/oraclejet-dom-driver -- ",
6
+ "clean": "rimraf dist",
7
+ "copy-files": "mergeJson package.json src/package-overrides.json dist/package.json",
8
+ "lint": "turbo run-lint --filter=@oracle/oraclejet-dom-driver -- ",
9
+ "run-build": "rollup -c rollup.config.mjs && yarn copy-files",
10
+ "run-check-types": "tsc --noEmit",
11
+ "run-lint": "eslint",
12
+ "test": "jest -c test/jest.config.js",
13
+ "test-ci-headless": "yarn test"
14
+ },
15
+ "type": "commonjs",
16
+ "exports": {
17
+ "./*": {
18
+ "types": "./*/index.d.ts",
19
+ "require": "./*/index.cjs",
20
+ "import": "./*/index.mjs"
21
+ }
22
+ },
23
+ "typesVersions": {
24
+ "*": {
25
+ "*": [
26
+ "./*/index.d.ts"
27
+ ]
28
+ }
29
+ },
30
+ "dependencies": {
31
+ "@oracle/oraclejet-testing": "19.0.0",
32
+ "@testing-library/user-event": "14.4.3"
33
+ },
34
+ "devDependencies": {
35
+ "@jest/globals": "29.6.2",
36
+ "@oracle/oraclejet-config-eslint": "workspace:*",
37
+ "@oracle/oraclejet-config-jest": "workspace:*",
38
+ "@oracle/oraclejet-config-typescript": "workspace:*",
39
+ "@oracle/oraclejet-internal-ws-build": "workspace:^",
40
+ "@testing-library/preact": "3.2.4",
41
+ "copyfiles": "2.4.1",
42
+ "eslint": "9.24.0",
43
+ "jest": "29.6.2",
44
+ "jest-environment-jsdom": "29.6.2",
45
+ "jsdom-global": "3.0.2",
46
+ "preact": "10.26.9",
47
+ "rimraf": "3.0.2",
48
+ "rollup": "2.70.2",
49
+ "ts-jest": "29.1.0",
50
+ "turbo": "2.3.3",
51
+ "typescript": "5.8.3",
52
+ "typescript-eslint": "8.29.1"
53
+ },
54
+ "version": "19.0.0"
55
+ }