Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
seleniumhq
GitHub Repository: seleniumhq/selenium
Path: blob/trunk/javascript/selenium-webdriver/test/bidi/generated/script_test.js
11822 views
1
// Licensed to the Software Freedom Conservancy (SFC) under one
2
// or more contributor license agreements. See the NOTICE file
3
// distributed with this work for additional information
4
// regarding copyright ownership. The SFC licenses this file
5
// to you under the Apache License, Version 2.0 (the
6
// "License"); you may not use this file except in compliance
7
// with the License. You may obtain a copy of the License at
8
//
9
// http://www.apache.org/licenses/LICENSE-2.0
10
//
11
// Unless required by applicable law or agreed to in writing,
12
// software distributed under the License is distributed on an
13
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14
// KIND, either express or implied. See the License for the
15
// specific language governing permissions and limitations
16
// under the License.
17
18
'use strict'
19
20
const assert = require('node:assert')
21
const { suite, Pages } = require('../../../lib/test')
22
const { Browser } = require('selenium-webdriver')
23
24
const { Script } = require('selenium-webdriver/bidi/generated/script')
25
26
suite(
27
function (env) {
28
let driver
29
let script
30
31
beforeEach(async function () {
32
driver = await env.builder().build()
33
script = await Script.create(driver)
34
})
35
36
afterEach(function () {
37
return driver.quit()
38
})
39
40
describe('evaluate', function () {
41
it('can evaluate a simple expression', async function () {
42
const contextId = await driver.getWindowHandle()
43
const result = await script.evaluate({
44
expression: '1 + 2',
45
target: { context: contextId },
46
awaitPromise: false,
47
})
48
49
assert.strictEqual(result.type, 'success')
50
assert.strictEqual(result.result.type, 'number')
51
assert.strictEqual(result.result.value, 3)
52
})
53
54
it('can evaluate a string expression', async function () {
55
const contextId = await driver.getWindowHandle()
56
const result = await script.evaluate({
57
expression: '"hello" + " " + "world"',
58
target: { context: contextId },
59
awaitPromise: false,
60
})
61
62
assert.strictEqual(result.type, 'success')
63
assert.strictEqual(result.result.type, 'string')
64
assert.strictEqual(result.result.value, 'hello world')
65
})
66
67
it('can evaluate a boolean expression', async function () {
68
const contextId = await driver.getWindowHandle()
69
const result = await script.evaluate({
70
expression: '1 === 1',
71
target: { context: contextId },
72
awaitPromise: false,
73
})
74
75
assert.strictEqual(result.type, 'success')
76
assert.strictEqual(result.result.type, 'boolean')
77
assert.strictEqual(result.result.value, true)
78
})
79
80
it('captures exception details on error', async function () {
81
const contextId = await driver.getWindowHandle()
82
const result = await script.evaluate({
83
expression: 'throw new Error("test error")',
84
target: { context: contextId },
85
awaitPromise: false,
86
})
87
88
assert.strictEqual(result.type, 'exception')
89
assert.ok(result.exceptionDetails)
90
assert.ok(result.exceptionDetails.text.includes('test error'))
91
})
92
93
it('can await a promise', async function () {
94
const contextId = await driver.getWindowHandle()
95
const result = await script.evaluate({
96
expression: 'Promise.resolve(42)',
97
target: { context: contextId },
98
awaitPromise: true,
99
})
100
101
assert.strictEqual(result.type, 'success')
102
assert.strictEqual(result.result.value, 42)
103
})
104
})
105
106
describe('callFunction', function () {
107
it('can call a function with no arguments', async function () {
108
const contextId = await driver.getWindowHandle()
109
const result = await script.callFunction({
110
functionDeclaration: '() => 1 + 2',
111
awaitPromise: false,
112
target: { context: contextId },
113
})
114
115
assert.strictEqual(result.type, 'success')
116
assert.strictEqual(result.result.value, 3)
117
})
118
119
it('can call a function with arguments', async function () {
120
const contextId = await driver.getWindowHandle()
121
const result = await script.callFunction({
122
functionDeclaration: '(a, b) => a + b',
123
awaitPromise: false,
124
target: { context: contextId },
125
arguments: [
126
{ type: 'number', value: 10 },
127
{ type: 'number', value: 5 },
128
],
129
})
130
131
assert.strictEqual(result.type, 'success')
132
assert.strictEqual(result.result.value, 15)
133
})
134
135
it('can call a function that returns a string', async function () {
136
const contextId = await driver.getWindowHandle()
137
const result = await script.callFunction({
138
functionDeclaration: '() => document.title',
139
awaitPromise: false,
140
target: { context: contextId },
141
})
142
143
assert.strictEqual(result.type, 'success')
144
assert.strictEqual(result.result.type, 'string')
145
})
146
147
it('can call a function that returns an array', async function () {
148
const contextId = await driver.getWindowHandle()
149
const result = await script.callFunction({
150
functionDeclaration: '() => [1, 2, 3]',
151
awaitPromise: false,
152
target: { context: contextId },
153
})
154
155
assert.strictEqual(result.type, 'success')
156
assert.strictEqual(result.result.type, 'array')
157
assert.ok(result.result.value)
158
})
159
160
it('can call a function in a sandbox', async function () {
161
const contextId = await driver.getWindowHandle()
162
const result = await script.callFunction({
163
functionDeclaration: '() => 42',
164
awaitPromise: false,
165
target: { context: contextId, sandbox: 'testSandbox' },
166
})
167
168
assert.strictEqual(result.type, 'success')
169
assert.strictEqual(result.result.value, 42)
170
})
171
172
it('captures exception in callFunction', async function () {
173
const contextId = await driver.getWindowHandle()
174
const result = await script.callFunction({
175
functionDeclaration: '() => { throw new TypeError("bad input") }',
176
awaitPromise: false,
177
target: { context: contextId },
178
})
179
180
assert.strictEqual(result.type, 'exception')
181
assert.ok(result.exceptionDetails)
182
})
183
})
184
185
describe('getRealms', function () {
186
it('can get all realms', async function () {
187
const contextId = await driver.getWindowHandle()
188
await driver.get(Pages.emptyPage)
189
190
const result = await script.getRealms({ context: contextId })
191
192
assert.ok(Array.isArray(result.realms))
193
assert.ok(result.realms.length > 0)
194
195
const windowRealm = result.realms.find((r) => r.type === 'window')
196
assert.ok(windowRealm, 'should have a window realm')
197
assert.ok(windowRealm.realm, 'realm id should be present')
198
assert.strictEqual(windowRealm.context, contextId)
199
})
200
201
it('can get realms filtered by type', async function () {
202
const contextId = await driver.getWindowHandle()
203
const result = await script.getRealms({ context: contextId, type: 'window' })
204
205
assert.ok(Array.isArray(result.realms))
206
assert.ok(result.realms.every((r) => r.type === 'window'))
207
})
208
209
it('can use a realm target for evaluate', async function () {
210
const contextId = await driver.getWindowHandle()
211
const realmsResult = await script.getRealms({ context: contextId })
212
const realmId = realmsResult.realms[0].realm
213
214
const evalResult = await script.evaluate({
215
expression: '2 * 21',
216
target: { realm: realmId },
217
awaitPromise: false,
218
})
219
220
assert.strictEqual(evalResult.type, 'success')
221
assert.strictEqual(evalResult.result.value, 42)
222
})
223
})
224
225
describe('preload scripts', function () {
226
it('can add and remove a preload script', async function () {
227
const result = await script.addPreloadScript({
228
functionDeclaration: '() => { window._testPreloaded = true; }',
229
})
230
231
assert.ok(result.script, 'script id should be returned')
232
assert.strictEqual(typeof result.script, 'string')
233
234
await script.removePreloadScript({ script: result.script })
235
})
236
237
it('preload script runs on new page navigation', async function () {
238
const preload = await script.addPreloadScript({
239
functionDeclaration: '() => { window._preloadedValue = 99; }',
240
})
241
242
await driver.get(Pages.emptyPage)
243
244
const contextId = await driver.getWindowHandle()
245
const result = await script.evaluate({
246
expression: 'window._preloadedValue',
247
target: { context: contextId },
248
awaitPromise: false,
249
})
250
251
assert.strictEqual(result.type, 'success')
252
assert.strictEqual(result.result.value, 99)
253
254
await script.removePreloadScript({ script: preload.script })
255
})
256
257
it('preload script scoped to a specific context', async function () {
258
const contextId = await driver.getWindowHandle()
259
260
const preload = await script.addPreloadScript({
261
functionDeclaration: '() => { window._scopedPreload = "scoped"; }',
262
contexts: [contextId],
263
})
264
265
assert.ok(preload.script)
266
267
await script.removePreloadScript({ script: preload.script })
268
})
269
})
270
271
describe('realm events', function () {
272
it('fires realmCreated when a new context is opened', async function () {
273
let realmCreated = null
274
275
await script.onRealmCreated((params) => {
276
if (params.type === 'window') {
277
realmCreated = params
278
}
279
})
280
281
// Opening a new window creates a new realm
282
await driver.switchTo().newWindow('tab')
283
await driver.wait(() => realmCreated !== null, 5000)
284
285
assert.ok(realmCreated, 'realmCreated event should have fired')
286
assert.strictEqual(realmCreated.type, 'window')
287
assert.ok(realmCreated.realm)
288
})
289
290
it('fires realmDestroyed when a context is closed', async function () {
291
const newHandle = await driver
292
.switchTo()
293
.newWindow('tab')
294
.then(() => driver.getWindowHandle())
295
296
let realmDestroyed = null
297
await script.onRealmDestroyed((params) => {
298
realmDestroyed = params
299
})
300
301
await driver.close()
302
await driver.wait(() => realmDestroyed !== null, 5000)
303
304
// Switch back to original window
305
const handles = await driver.getAllWindowHandles()
306
await driver.switchTo().window(handles[0])
307
308
assert.ok(realmDestroyed, 'realmDestroyed event should have fired')
309
assert.ok(realmDestroyed.realm)
310
})
311
})
312
},
313
{ browsers: [Browser.CHROME, Browser.FIREFOX] },
314
)
315
316