@web/test-runner-commands 0.6.4 → 0.6.5

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.
@@ -69,6 +69,10 @@ export function sendKeys(options) {
69
69
  return executeServerCommand('send-keys', options);
70
70
  }
71
71
 
72
+ export function selectOption(options) {
73
+ return executeServerCommand('select-option', options);
74
+ }
75
+
72
76
  export function sendMouse(options) {
73
77
  return executeServerCommand('send-mouse', options);
74
78
  }
@@ -0,0 +1,17 @@
1
+ import { TestRunnerPlugin } from '@web/test-runner-core';
2
+ declare type SelectByValuePayload = {
3
+ selector: string;
4
+ value: string;
5
+ };
6
+ declare type SelectByLabelPayload = {
7
+ selector: string;
8
+ label: string;
9
+ };
10
+ declare type SelectMultipleValuesPayload = {
11
+ selector: string;
12
+ values: string[];
13
+ };
14
+ export declare type SelectOptionPayload = SelectByLabelPayload | SelectByValuePayload | SelectMultipleValuesPayload;
15
+ export declare function selectOptionPlugin(): TestRunnerPlugin<SelectOptionPayload>;
16
+ export {};
17
+ //# sourceMappingURL=selectOptionPlugin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"selectOptionPlugin.d.ts","sourceRoot":"","sources":["../src/selectOptionPlugin.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAIzD,aAAK,oBAAoB,GAAG;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAChE,aAAK,oBAAoB,GAAG;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAChE,aAAK,2BAA2B,GAAG;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC;AAE1E,oBAAY,mBAAmB,GAC3B,oBAAoB,GACpB,oBAAoB,GACpB,2BAA2B,CAAC;AA8ChC,wBAAgB,kBAAkB,IAAI,gBAAgB,CAAC,mBAAmB,CAAC,CAgE1E"}
@@ -0,0 +1,97 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.selectOptionPlugin = void 0;
4
+ function isObject(payload) {
5
+ return payload != null && typeof payload === 'object';
6
+ }
7
+ function isSelectOptionPayload(payload) {
8
+ const validOptions = ['value', 'label', 'values'];
9
+ if (!isObject(payload))
10
+ throw new Error('You must provide a `SelectOptionPayload` object');
11
+ if (!payload.selector || typeof payload.selector !== 'string') {
12
+ throw new Error(`You must provide a selector representing the select you wish to locate`);
13
+ }
14
+ const numberOfValidOptions = Object.keys(payload).filter(key => validOptions.includes(key)).length;
15
+ const unknownOptions = Object.keys(payload).filter(key => ![...validOptions, 'selector'].includes(key));
16
+ if (numberOfValidOptions === 0)
17
+ throw new Error(`You must provide one of the following properties to pass to the browser runner: ${validOptions.join(', ')}.`);
18
+ if (unknownOptions.length > 0) {
19
+ throw new Error('Unknown options `' + unknownOptions.join(', ') + '` present.');
20
+ }
21
+ return true;
22
+ }
23
+ function isValuePayload(payload) {
24
+ return 'selector' in payload && 'value' in payload;
25
+ }
26
+ function isLabelPayload(payload) {
27
+ return 'selector' in payload && 'label' in payload;
28
+ }
29
+ function isMultiplePayload(payload) {
30
+ return 'selector' in payload && 'values' in payload;
31
+ }
32
+ function selectOptionPlugin() {
33
+ return {
34
+ name: 'select-option-command',
35
+ async executeCommand({ command, payload, session }) {
36
+ if (command === 'select-option') {
37
+ if (!isSelectOptionPayload(payload) || !payload) {
38
+ throw new Error('You must provide a `SelectOptionPayload` object');
39
+ }
40
+ // handle specific behavior for playwright
41
+ if (session.browser.type === 'playwright') {
42
+ const page = session.browser.getPage(session.id);
43
+ if (isValuePayload(payload)) {
44
+ const { selector, value } = payload;
45
+ await page.locator(selector).selectOption(value);
46
+ return true;
47
+ }
48
+ else if (isLabelPayload(payload)) {
49
+ const { selector, label } = payload;
50
+ await page.locator(selector).selectOption({ label });
51
+ return true;
52
+ }
53
+ else if (isMultiplePayload(payload)) {
54
+ const { selector, values } = payload;
55
+ await page.locator(selector).selectOption([...values]);
56
+ return true;
57
+ }
58
+ }
59
+ // handle specific behavior for puppeteer
60
+ if (session.browser.type === 'puppeteer') {
61
+ const page = session.browser.getPage(session.id);
62
+ if (isValuePayload(payload)) {
63
+ const { selector, value } = payload;
64
+ await page.select(selector, value);
65
+ return true;
66
+ }
67
+ else if (isMultiplePayload(payload)) {
68
+ const { selector, values } = payload;
69
+ await page.select(selector, ...values);
70
+ return true;
71
+ }
72
+ else {
73
+ throw new Error(`Puppeteer only supports selection of an option by its value(s):
74
+ https://pptr.dev/next/api/puppeteer.page.select#parameters
75
+ `);
76
+ }
77
+ }
78
+ // handle specific behavior for webdriver
79
+ if (session.browser.type === 'webdriver') {
80
+ throw new Error(`Selecting an option via a browser driver command is not currently implemented in WebDriver yet.
81
+ https://www.selenium.dev/documentation/webdriver/elements/select_lists/
82
+
83
+ When using WebDriver, the current recommended (September 2022) approach is to:
84
+ - locate your select element (via querySelector or querySelectorAll)
85
+ - focus the element
86
+ - use sendKeys() to type the label of the option you wish to select
87
+ - use select.dispatchEvent(new Event('change')) to trigger a change event on the select.
88
+ `);
89
+ }
90
+ // you might not be able to support all browser launchers
91
+ throw new Error(`Selection of select element options is not supported for browser type ${session.browser.type}.`);
92
+ }
93
+ },
94
+ };
95
+ }
96
+ exports.selectOptionPlugin = selectOptionPlugin;
97
+ //# sourceMappingURL=selectOptionPlugin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"selectOptionPlugin.js","sourceRoot":"","sources":["../src/selectOptionPlugin.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@web/test-runner-commands",
3
- "version": "0.6.4",
3
+ "version": "0.6.5",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -0,0 +1,122 @@
1
+ import { TestRunnerPlugin } from '@web/test-runner-core';
2
+ import type { ChromeLauncher } from '@web/test-runner-chrome';
3
+ import type { PlaywrightLauncher } from '@web/test-runner-playwright';
4
+
5
+ type SelectByValuePayload = { selector: string; value: string };
6
+ type SelectByLabelPayload = { selector: string; label: string };
7
+ type SelectMultipleValuesPayload = { selector: string; values: string[] };
8
+
9
+ export type SelectOptionPayload =
10
+ | SelectByLabelPayload
11
+ | SelectByValuePayload
12
+ | SelectMultipleValuesPayload;
13
+
14
+ function isObject(payload: unknown): payload is Record<string, unknown> {
15
+ return payload != null && typeof payload === 'object';
16
+ }
17
+
18
+ function isSelectOptionPayload(payload: unknown): boolean {
19
+ const validOptions = ['value', 'label', 'values'];
20
+
21
+ if (!isObject(payload)) throw new Error('You must provide a `SelectOptionPayload` object');
22
+
23
+ if (!payload.selector || typeof payload.selector !== 'string') {
24
+ throw new Error(`You must provide a selector representing the select you wish to locate`);
25
+ }
26
+
27
+ const numberOfValidOptions = Object.keys(payload).filter(key =>
28
+ validOptions.includes(key),
29
+ ).length;
30
+ const unknownOptions = Object.keys(payload).filter(
31
+ key => ![...validOptions, 'selector'].includes(key),
32
+ );
33
+
34
+ if (numberOfValidOptions === 0)
35
+ throw new Error(
36
+ `You must provide one of the following properties to pass to the browser runner: ${validOptions.join(
37
+ ', ',
38
+ )}.`,
39
+ );
40
+ if (unknownOptions.length > 0) {
41
+ throw new Error('Unknown options `' + unknownOptions.join(', ') + '` present.');
42
+ }
43
+ return true;
44
+ }
45
+
46
+ function isValuePayload(payload: SelectOptionPayload): payload is SelectByValuePayload {
47
+ return 'selector' in payload && 'value' in payload;
48
+ }
49
+
50
+ function isLabelPayload(payload: SelectOptionPayload): payload is SelectByLabelPayload {
51
+ return 'selector' in payload && 'label' in payload;
52
+ }
53
+
54
+ function isMultiplePayload(payload: SelectOptionPayload): payload is SelectMultipleValuesPayload {
55
+ return 'selector' in payload && 'values' in payload;
56
+ }
57
+
58
+ export function selectOptionPlugin(): TestRunnerPlugin<SelectOptionPayload> {
59
+ return {
60
+ name: 'select-option-command',
61
+ async executeCommand({ command, payload, session }): Promise<any> {
62
+ if (command === 'select-option') {
63
+ if (!isSelectOptionPayload(payload) || !payload) {
64
+ throw new Error('You must provide a `SelectOptionPayload` object');
65
+ }
66
+ // handle specific behavior for playwright
67
+ if (session.browser.type === 'playwright') {
68
+ const page = (session.browser as PlaywrightLauncher).getPage(session.id);
69
+ if (isValuePayload(payload)) {
70
+ const { selector, value } = payload;
71
+ await page.locator(selector).selectOption(value);
72
+ return true;
73
+ } else if (isLabelPayload(payload)) {
74
+ const { selector, label } = payload;
75
+ await page.locator(selector).selectOption({ label });
76
+ return true;
77
+ } else if (isMultiplePayload(payload)) {
78
+ const { selector, values } = payload;
79
+ await page.locator(selector).selectOption([...values]);
80
+ return true;
81
+ }
82
+ }
83
+
84
+ // handle specific behavior for puppeteer
85
+ if (session.browser.type === 'puppeteer') {
86
+ const page = (session.browser as ChromeLauncher).getPage(session.id);
87
+ if (isValuePayload(payload)) {
88
+ const { selector, value } = payload;
89
+ await page.select(selector, value);
90
+ return true;
91
+ } else if (isMultiplePayload(payload)) {
92
+ const { selector, values } = payload;
93
+ await page.select(selector, ...values);
94
+ return true;
95
+ } else {
96
+ throw new Error(`Puppeteer only supports selection of an option by its value(s):
97
+ https://pptr.dev/next/api/puppeteer.page.select#parameters
98
+ `);
99
+ }
100
+ }
101
+
102
+ // handle specific behavior for webdriver
103
+ if (session.browser.type === 'webdriver') {
104
+ throw new Error(`Selecting an option via a browser driver command is not currently implemented in WebDriver yet.
105
+ https://www.selenium.dev/documentation/webdriver/elements/select_lists/
106
+
107
+ When using WebDriver, the current recommended (September 2022) approach is to:
108
+ - locate your select element (via querySelector or querySelectorAll)
109
+ - focus the element
110
+ - use sendKeys() to type the label of the option you wish to select
111
+ - use select.dispatchEvent(new Event('change')) to trigger a change event on the select.
112
+ `);
113
+ }
114
+
115
+ // you might not be able to support all browser launchers
116
+ throw new Error(
117
+ `Selection of select element options is not supported for browser type ${session.browser.type}.`,
118
+ );
119
+ }
120
+ },
121
+ };
122
+ }