1 | "use strict";
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 | var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
13 | if (k2 === undefined) k2 = k;
|
14 | Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
15 | }) : (function(o, m, k, k2) {
|
16 | if (k2 === undefined) k2 = k;
|
17 | o[k2] = m[k];
|
18 | }));
|
19 | var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
20 | Object.defineProperty(o, "default", { enumerable: true, value: v });
|
21 | }) : function(o, v) {
|
22 | o["default"] = v;
|
23 | });
|
24 | var __importStar = (this && this.__importStar) || function (mod) {
|
25 | if (mod && mod.__esModule) return mod;
|
26 | var result = {};
|
27 | if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
28 | __setModuleDefault(result, mod);
|
29 | return result;
|
30 | };
|
31 | Object.defineProperty(exports, "__esModule", { value: true });
|
32 | exports.openAndSwitchToNewTab = exports.makeDriver = exports.validateBrowserConfig = exports.parseBrowserConfigString = exports.browserSignature = exports.fcpBrowsers = exports.supportedBrowsers = void 0;
|
33 | const webdriver = __importStar(require("selenium-webdriver"));
|
34 | const chrome = __importStar(require("selenium-webdriver/chrome"));
|
35 | const edge = __importStar(require("selenium-webdriver/edge"));
|
36 | const firefox = __importStar(require("selenium-webdriver/firefox"));
|
37 | const install_1 = require("./install");
|
38 | const util_1 = require("./util");
|
39 |
|
40 | exports.supportedBrowsers = new Set([
|
41 | 'chrome',
|
42 | 'firefox',
|
43 | 'safari',
|
44 | 'edge',
|
45 | 'ie',
|
46 | ]);
|
47 |
|
48 |
|
49 |
|
50 | const browserWebdriverModules = new Map([
|
51 | ['chrome', 'chromedriver'],
|
52 | ['firefox', 'geckodriver'],
|
53 | ['ie', 'iedriver'],
|
54 | ]);
|
55 |
|
56 | const webdriverBrowserNames = new Map([
|
57 | ['edge', 'MicrosoftEdge'],
|
58 | ['ie', 'internet explorer'],
|
59 | ]);
|
60 |
|
61 | const headlessBrowsers = new Set(['chrome', 'firefox']);
|
62 |
|
63 | exports.fcpBrowsers = new Set(['chrome']);
|
64 |
|
65 |
|
66 |
|
67 | function browserSignature(config) {
|
68 | var _a, _b, _c, _d, _e, _f;
|
69 | return JSON.stringify([
|
70 | config.name,
|
71 | config.headless,
|
72 | (_a = config.remoteUrl) !== null && _a !== void 0 ? _a : '',
|
73 | config.windowSize.width,
|
74 | config.windowSize.height,
|
75 | (_b = config.binary) !== null && _b !== void 0 ? _b : '',
|
76 | (_c = config.addArguments) !== null && _c !== void 0 ? _c : [],
|
77 | (_d = config.removeArguments) !== null && _d !== void 0 ? _d : [],
|
78 | (_e = config.cpuThrottlingRate) !== null && _e !== void 0 ? _e : 1,
|
79 | (_f = config.preferences) !== null && _f !== void 0 ? _f : {},
|
80 | ]);
|
81 | }
|
82 | exports.browserSignature = browserSignature;
|
83 |
|
84 |
|
85 |
|
86 |
|
87 |
|
88 |
|
89 |
|
90 | function parseBrowserConfigString(str) {
|
91 | let remoteUrl;
|
92 | const at = str.indexOf('@');
|
93 | if (at !== -1) {
|
94 | remoteUrl = str.substring(at + 1);
|
95 | str = str.substring(0, at);
|
96 | }
|
97 | const headless = str.endsWith('-headless');
|
98 | if (headless === true) {
|
99 | str = str.replace(/-headless$/, '');
|
100 | }
|
101 | const name = str;
|
102 | const config = { name, headless };
|
103 | if (remoteUrl !== undefined) {
|
104 | config.remoteUrl = remoteUrl;
|
105 | }
|
106 | return config;
|
107 | }
|
108 | exports.parseBrowserConfigString = parseBrowserConfigString;
|
109 |
|
110 |
|
111 |
|
112 | function validateBrowserConfig({ name, headless, remoteUrl, windowSize, }) {
|
113 | if (!exports.supportedBrowsers.has(name)) {
|
114 | throw new Error(`Browser ${name} is not supported, ` +
|
115 | `only ${[...exports.supportedBrowsers].join(', ')} are currently supported.`);
|
116 | }
|
117 | if (headless === true && !headlessBrowsers.has(name)) {
|
118 | throw new Error(`Browser ${name} does not support headless mode.`);
|
119 | }
|
120 | if (remoteUrl !== undefined && !util_1.isHttpUrl(remoteUrl)) {
|
121 | throw new Error(`Invalid browser remote URL "${remoteUrl}".`);
|
122 | }
|
123 | if (windowSize.width < 0 || windowSize.height < 0) {
|
124 | throw new Error(`Invalid window size, width and height must be >= 0.`);
|
125 | }
|
126 | }
|
127 | exports.validateBrowserConfig = validateBrowserConfig;
|
128 |
|
129 |
|
130 |
|
131 | async function makeDriver(config) {
|
132 | const browserName = config.name;
|
133 | const webdriverModuleName = browserWebdriverModules.get(browserName);
|
134 | if (webdriverModuleName != null) {
|
135 | await install_1.installOnDemand(webdriverModuleName);
|
136 | require(webdriverModuleName);
|
137 | }
|
138 | const builder = new webdriver.Builder();
|
139 | const webdriverName = webdriverBrowserNames.get(config.name) || config.name;
|
140 | builder.forBrowser(webdriverName);
|
141 | builder.setChromeOptions(chromeOpts(config));
|
142 | builder.setFirefoxOptions(firefoxOpts(config));
|
143 | if (config.remoteUrl !== undefined) {
|
144 | builder.usingServer(config.remoteUrl);
|
145 | }
|
146 | else if (config.name === 'edge') {
|
147 |
|
148 |
|
149 |
|
150 |
|
151 |
|
152 | builder.setEdgeService(new edge.ServiceBuilder());
|
153 | }
|
154 | const driver = await builder.build();
|
155 | if (config.name === 'safari' || config.name === 'edge' ||
|
156 | config.name === 'ie') {
|
157 |
|
158 |
|
159 |
|
160 |
|
161 | const rect = config.name === 'safari' ? Object.assign(Object.assign({}, config.windowSize), { x: 0, y: 0 }) :
|
162 | config.windowSize;
|
163 | await driver.manage().window().setRect(rect);
|
164 | }
|
165 | return driver;
|
166 | }
|
167 | exports.makeDriver = makeDriver;
|
168 | function chromeOpts(config) {
|
169 | const opts = new chrome.Options();
|
170 | if (config.binary) {
|
171 | opts.setChromeBinaryPath(config.binary);
|
172 | }
|
173 | if (config.headless === true) {
|
174 | opts.addArguments('--headless');
|
175 | }
|
176 | if (config.addArguments) {
|
177 | opts.addArguments(...config.addArguments);
|
178 | }
|
179 | if (config.removeArguments) {
|
180 | opts.excludeSwitches(...config.removeArguments);
|
181 | }
|
182 | const { width, height } = config.windowSize;
|
183 | opts.addArguments(`--window-size=${width},${height}`);
|
184 | return opts;
|
185 | }
|
186 | function firefoxOpts(config) {
|
187 | const opts = new firefox.Options();
|
188 | if (config.preferences) {
|
189 | for (const [name, value] of Object.entries(config.preferences)) {
|
190 | opts.setPreference(name, value);
|
191 | }
|
192 | }
|
193 | if (config.binary) {
|
194 | opts.setBinary(config.binary);
|
195 | }
|
196 | if (config.headless === true) {
|
197 |
|
198 | opts.addArguments('-headless');
|
199 | }
|
200 | const { width, height } = config.windowSize;
|
201 |
|
202 | opts.addArguments(`-width=${width}`);
|
203 |
|
204 | opts.addArguments(`-height=${height}`);
|
205 | return opts;
|
206 | }
|
207 |
|
208 |
|
209 |
|
210 |
|
211 |
|
212 | async function openAndSwitchToNewTab(driver, config) {
|
213 |
|
214 |
|
215 |
|
216 | const tabsBefore = await driver.getAllWindowHandles();
|
217 | if (tabsBefore.length !== 1) {
|
218 | throw new Error(`Expected only 1 open tab, got ${tabsBefore.length}`);
|
219 | }
|
220 |
|
221 |
|
222 |
|
223 |
|
224 |
|
225 |
|
226 | await driver.executeScript('window.open("", "", "noopener=yes");');
|
227 |
|
228 |
|
229 | const maxRetries = 20;
|
230 | const retrySleepMs = 250;
|
231 | let retries = 0;
|
232 | let newTabId;
|
233 | while (true) {
|
234 | const tabsAfter = await driver.getAllWindowHandles();
|
235 | const newTabs = tabsAfter.filter((tab) => tab !== tabsBefore[0]);
|
236 | if (newTabs.length === 1) {
|
237 | newTabId = newTabs[0];
|
238 | break;
|
239 | }
|
240 | retries++;
|
241 | if (newTabs.length > 1 || retries > maxRetries) {
|
242 | throw new Error(`Expected to create 1 new tab, got ${newTabs.length}`);
|
243 | }
|
244 | await new Promise((resolve) => setTimeout(resolve, retrySleepMs));
|
245 | }
|
246 | await driver.switchTo().window(newTabId);
|
247 | if (config.name === 'ie' || config.name === 'safari') {
|
248 |
|
249 |
|
250 | const rect = config.name === 'safari' ? Object.assign(Object.assign({}, config.windowSize), { x: 0, y: 0 }) :
|
251 | config.windowSize;
|
252 | await driver.manage().window().setRect(rect);
|
253 | }
|
254 | const driverWithSendDevToolsCommand = driver;
|
255 | if (driverWithSendDevToolsCommand.sendDevToolsCommand &&
|
256 | config.cpuThrottlingRate !== undefined) {
|
257 |
|
258 | await driverWithSendDevToolsCommand.sendDevToolsCommand('Emulation.setCPUThrottlingRate', { rate: config.cpuThrottlingRate });
|
259 | }
|
260 | }
|
261 | exports.openAndSwitchToNewTab = openAndSwitchToNewTab;
|
262 |
|
\ | No newline at end of file |