selenium-webdriver 4.8.2 → 4.9.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,325 @@
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
+ const {
19
+ EvaluateResultType,
20
+ EvaluateResultSuccess,
21
+ EvaluateResultException,
22
+ ExceptionDetails,
23
+ } = require('./evaluateResult')
24
+ const { RealmInfo } = require('./realmInfo')
25
+ const { RemoteValue } = require('./protocolValue')
26
+
27
+ class ScriptManager {
28
+ constructor(driver) {
29
+ this._driver = driver
30
+ }
31
+
32
+ async init(browsingContextId) {
33
+ if (!(await this._driver.getCapabilities()).get('webSocketUrl')) {
34
+ throw Error('WebDriver instance must support BiDi protocol')
35
+ }
36
+
37
+ this.bidi = await this._driver.getBidi()
38
+ this._browsingContextId = browsingContextId
39
+ }
40
+
41
+ async disownRealmScript(realmId, handles) {
42
+ const params = {
43
+ method: 'script.disown',
44
+ params: {
45
+ handles: handles,
46
+ target: {
47
+ realm: realmId,
48
+ },
49
+ },
50
+ }
51
+
52
+ await this.bidi.send(params)
53
+ }
54
+
55
+ async disownBrowsingContextScript(
56
+ browsingContextId,
57
+ handles,
58
+ sandbox = null
59
+ ) {
60
+ const params = {
61
+ method: 'script.disown',
62
+ params: {
63
+ handles: handles,
64
+ target: {
65
+ context: browsingContextId,
66
+ },
67
+ },
68
+ }
69
+
70
+ if (sandbox != null) {
71
+ params.params.target['sandbox'] = sandbox
72
+ }
73
+
74
+ await this.bidi.send(params)
75
+ }
76
+
77
+ async callFunctionInRealm(
78
+ realmId,
79
+ functionDeclaration,
80
+ awaitPromise,
81
+ argumentValueList = null,
82
+ thisParameter = null,
83
+ resultOwnership = null
84
+ ) {
85
+ const params = this.getCallFunctionParams(
86
+ 'realm',
87
+ realmId,
88
+ null,
89
+ functionDeclaration,
90
+ awaitPromise,
91
+ argumentValueList,
92
+ thisParameter,
93
+ resultOwnership
94
+ )
95
+
96
+ const command = {
97
+ method: 'script.callFunction',
98
+ params,
99
+ }
100
+
101
+ let response = await this.bidi.send(command)
102
+ return this.createEvaluateResult(response)
103
+ }
104
+
105
+ async callFunctionInBrowsingContext(
106
+ browsingContextId,
107
+ functionDeclaration,
108
+ awaitPromise,
109
+ argumentValueList = null,
110
+ thisParameter = null,
111
+ resultOwnership = null,
112
+ sandbox = null
113
+ ) {
114
+ const params = this.getCallFunctionParams(
115
+ 'contextTarget',
116
+ browsingContextId,
117
+ sandbox,
118
+ functionDeclaration,
119
+ awaitPromise,
120
+ argumentValueList,
121
+ thisParameter,
122
+ resultOwnership
123
+ )
124
+
125
+ const command = {
126
+ method: 'script.callFunction',
127
+ params,
128
+ }
129
+ const response = await this.bidi.send(command)
130
+ return this.createEvaluateResult(response)
131
+ }
132
+
133
+ async evaluateFunctionInRealm(
134
+ realmId,
135
+ expression,
136
+ awaitPromise,
137
+ resultOwnership = null
138
+ ) {
139
+ const params = this.getEvaluateParams(
140
+ 'realm',
141
+ realmId,
142
+ null,
143
+ expression,
144
+ awaitPromise,
145
+ resultOwnership
146
+ )
147
+
148
+ const command = {
149
+ method: 'script.evaluate',
150
+ params,
151
+ }
152
+
153
+ let response = await this.bidi.send(command)
154
+ return this.createEvaluateResult(response)
155
+ }
156
+
157
+ async evaluateFunctionInBrowsingContext(
158
+ browsingContextId,
159
+ expression,
160
+ awaitPromise,
161
+ resultOwnership = null,
162
+ sandbox = null
163
+ ) {
164
+ const params = this.getEvaluateParams(
165
+ 'contextTarget',
166
+ browsingContextId,
167
+ sandbox,
168
+ expression,
169
+ awaitPromise,
170
+ resultOwnership
171
+ )
172
+
173
+ const command = {
174
+ method: 'script.evaluate',
175
+ params,
176
+ }
177
+
178
+ let response = await this.bidi.send(command)
179
+ return this.createEvaluateResult(response)
180
+ }
181
+
182
+ getCallFunctionParams(
183
+ targetType,
184
+ id,
185
+ sandbox,
186
+ functionDeclaration,
187
+ awaitPromise,
188
+ argumentValueList = null,
189
+ thisParameter = null,
190
+ resultOwnership = null
191
+ ) {
192
+ const params = {
193
+ functionDeclaration: functionDeclaration,
194
+ awaitPromise: awaitPromise,
195
+ }
196
+ if (targetType === 'contextTarget') {
197
+ if (sandbox != null) {
198
+ params['target'] = { context: id, sandbox: sandbox }
199
+ } else {
200
+ params['target'] = { context: id }
201
+ }
202
+ } else {
203
+ params['target'] = { realm: id }
204
+ }
205
+
206
+ if (argumentValueList != null) {
207
+ let argumentParams = []
208
+ argumentValueList.forEach((argumentValue) => {
209
+ argumentParams.push(argumentValue.asMap())
210
+ })
211
+ params['arguments'] = argumentParams
212
+ }
213
+
214
+ if (thisParameter != null) {
215
+ params['this'] = thisParameter
216
+ }
217
+
218
+ if (resultOwnership != null) {
219
+ params['resultOwnership'] = resultOwnership
220
+ }
221
+
222
+ return params
223
+ }
224
+
225
+ getEvaluateParams(
226
+ targetType,
227
+ id,
228
+ sandbox,
229
+ expression,
230
+ awaitPromise,
231
+ resultOwnership = null
232
+ ) {
233
+ const params = {
234
+ expression: expression,
235
+ awaitPromise: awaitPromise,
236
+ }
237
+ if (targetType === 'contextTarget') {
238
+ if (sandbox != null) {
239
+ params['target'] = { context: id, sandbox: sandbox }
240
+ } else {
241
+ params['target'] = { context: id }
242
+ }
243
+ } else {
244
+ params['target'] = { realm: id }
245
+ }
246
+ if (resultOwnership != null) {
247
+ params['resultOwnership'] = resultOwnership
248
+ }
249
+
250
+ return params
251
+ }
252
+
253
+ createEvaluateResult(response) {
254
+ var type = response.result.type
255
+ var realmId = response.result.realm
256
+ var evaluateResult
257
+
258
+ if (type === EvaluateResultType.SUCCESS) {
259
+ var result = response.result.result
260
+ evaluateResult = new EvaluateResultSuccess(
261
+ realmId,
262
+ new RemoteValue(result)
263
+ )
264
+ } else {
265
+ var exceptionDetails = response.result.exceptionDetails
266
+ evaluateResult = new EvaluateResultException(
267
+ realmId,
268
+ new ExceptionDetails(exceptionDetails)
269
+ )
270
+ }
271
+ return evaluateResult
272
+ }
273
+
274
+ realmInfoMapper(realms) {
275
+ var realmsList = []
276
+ realms.forEach((realm) => {
277
+ realmsList.push(RealmInfo.fromJson(realm))
278
+ })
279
+ return realmsList
280
+ }
281
+
282
+ async getAllRealms() {
283
+ const command = {
284
+ method: 'script.getRealms',
285
+ params: {},
286
+ }
287
+ let response = await this.bidi.send(command)
288
+ return this.realmInfoMapper(response.result.realms)
289
+ }
290
+
291
+ async getRealmsByType(type) {
292
+ const command = {
293
+ method: 'script.getRealms',
294
+ params: { type: type },
295
+ }
296
+ let response = await this.bidi.send(command)
297
+ return this.realmInfoMapper(response.result.realms)
298
+ }
299
+
300
+ async getRealmsInBrowsingContext(browsingContext) {
301
+ const command = {
302
+ method: 'script.getRealms',
303
+ params: { context: browsingContext },
304
+ }
305
+ let response = await this.bidi.send(command)
306
+ return this.realmInfoMapper(response.result.realms)
307
+ }
308
+
309
+ async getRealmsInBrowsingContextByType(browsingContext, type) {
310
+ const command = {
311
+ method: 'script.getRealms',
312
+ params: { context: browsingContext, type: type },
313
+ }
314
+ let response = await this.bidi.send(command)
315
+ return this.realmInfoMapper(response.result.realms)
316
+ }
317
+ }
318
+
319
+ async function getScriptManagerInstance(browsingContextId, driver) {
320
+ let instance = new ScriptManager(driver)
321
+ await instance.init(browsingContextId)
322
+ return instance
323
+ }
324
+
325
+ module.exports = getScriptManagerInstance
Binary file
Binary file
Binary file
package/chrome.js CHANGED
@@ -130,7 +130,6 @@
130
130
  const io = require('./io')
131
131
  const { Browser } = require('./lib/capabilities')
132
132
  const chromium = require('./chromium')
133
- const { driverLocation } = require('./common/seleniumManager')
134
133
 
135
134
  /**
136
135
  * Name of the ChromeDriver executable.
@@ -158,23 +157,6 @@ class ServiceBuilder extends chromium.ServiceBuilder {
158
157
  */
159
158
  constructor(opt_exe) {
160
159
  let exe = opt_exe || locateSynchronously()
161
-
162
- if (!exe) {
163
- try {
164
- exe = driverLocation(Browser.CHROME)
165
- } catch (err) {
166
- console.log(`Unable to obtain driver using Selenium Manager: ${err}`)
167
- }
168
- }
169
-
170
- if (!exe) {
171
- throw Error(
172
- `ChromeDriver could not be found on the PATH.
173
- For more information on how to install drivers see
174
- https://www.selenium.dev/documentation/webdriver/getting_started/install_drivers/.`
175
- )
176
- }
177
-
178
160
  super(exe)
179
161
  }
180
162
  }
package/chromium.js CHANGED
@@ -83,6 +83,7 @@ const error = require('./lib/error')
83
83
  const Symbols = require('./lib/symbols')
84
84
  const webdriver = require('./lib/webdriver')
85
85
  const remote = require('./remote')
86
+ const { getPath } = require('./common/driverFinder')
86
87
 
87
88
  /**
88
89
  * Custom command names supported by Chromium WebDriver.
@@ -684,6 +685,9 @@ class Driver extends webdriver.WebDriver {
684
685
  configureExecutor(executor, this.VENDOR_COMMAND_PREFIX)
685
686
  } else {
686
687
  let service = opt_serviceExecutor || this.getDefaultService()
688
+ if (!service.getExecutable()) {
689
+ service.setExecutable(getPath(service, caps))
690
+ }
687
691
  onQuit = () => service.kill()
688
692
  executor = createExecutor(service.start(), this.VENDOR_COMMAND_PREFIX)
689
693
  }
@@ -0,0 +1,59 @@
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
+ /**
19
+ * This implementation is still in beta, and may change.
20
+ *
21
+ * Utility to find if a given file is present and executable.
22
+ */
23
+
24
+ const { driverLocation } = require('./seleniumManager')
25
+ const fs = require('fs')
26
+
27
+ /**
28
+ * Determines the path of the correct Selenium Manager binary
29
+ * @returns {string}
30
+ */
31
+ function getPath(service, capabilities) {
32
+ try {
33
+ return pathExists(service.getExecutable()) || driverLocation(capabilities)
34
+ } catch (e) {
35
+ throw Error(
36
+ `Unable to obtain browser driver.
37
+ For more information on how to install drivers see
38
+ https://www.selenium.dev/documentation/webdriver/getting_started/install_drivers/. ${e}`
39
+ )
40
+ }
41
+ }
42
+
43
+ /**
44
+ * _Synchronously_ attempts to locate the driver executable on the current
45
+ * system.
46
+ *
47
+ * @param {!string} driverPath
48
+ *
49
+ * @return {?string} the located executable, or `null`.
50
+ */
51
+ function pathExists(driverPath) {
52
+ if (!driverPath || !fs.existsSync(driverPath)) {
53
+ return null
54
+ }
55
+ return driverPath
56
+ }
57
+
58
+ // PUBLIC API
59
+ module.exports = { getPath }
@@ -24,13 +24,13 @@
24
24
  const { platform } = require('process')
25
25
  const path = require('path')
26
26
  const fs = require('fs')
27
- const execSync = require('child_process').execSync
27
+ const spawnSync = require('child_process').spawnSync
28
28
 
29
29
  /**
30
30
  * currently supported browsers for selenium-manager
31
31
  * @type {string[]}
32
32
  */
33
- const Browser = ['chrome', 'firefox', 'edge', 'iexplorer']
33
+ const Browser = ['chrome', 'firefox', 'edge', 'MicrosoftEdge', 'iexplorer']
34
34
 
35
35
  /**
36
36
  * Determines the path of the correct Selenium Manager binary
@@ -47,7 +47,14 @@ function getBinary() {
47
47
  const file =
48
48
  directory === 'windows' ? 'selenium-manager.exe' : 'selenium-manager'
49
49
 
50
- const filePath = path.join(__dirname, '..', '/bin', directory, file)
50
+ let seleniumManagerBasePath
51
+ if (process.env.SELENIUM_MANAGER_BASE_PATH) {
52
+ seleniumManagerBasePath = process.env.SELENIUM_MANAGER_BASE_PATH
53
+ } else {
54
+ seleniumManagerBasePath = path.join(__dirname, '..', '/bin')
55
+ }
56
+
57
+ const filePath = path.join(seleniumManagerBasePath, directory, file)
51
58
 
52
59
  if (!fs.existsSync(filePath)) {
53
60
  throw new Error(`Unable to obtain Selenium Manager`)
@@ -58,35 +65,55 @@ function getBinary() {
58
65
 
59
66
  /**
60
67
  * Determines the path of the correct driver
61
- * @param {Browser|string} browser name to fetch the driver
68
+ * @param {Capabilities} options browser options to fetch the driver
62
69
  * @returns {string} path of the driver location
63
70
  */
64
71
 
65
- function driverLocation(browser) {
66
- if (!Browser.includes(browser.toLocaleString())) {
72
+ function driverLocation(options) {
73
+ if (!Browser.includes(options.getBrowserName().toLocaleString())) {
67
74
  throw new Error(
68
- `Unable to locate driver associated with browser name: ${browser}`
75
+ `Unable to locate driver associated with browser name: ${options.getBrowserName()}`
69
76
  )
70
77
  }
71
78
 
72
- let args = [getBinary(), '--browser', browser, '--output', 'json']
73
- let output
79
+ let args = ['--browser', options.getBrowserName(), '--output', 'json']
80
+
81
+ if (options.getBrowserVersion() && options.getBrowserVersion() !== "") {
82
+ args.push("--browser-version", options.getBrowserVersion())
83
+ }
84
+
85
+ const vendorOptions = options.get('goog:chromeOptions') || options.get('ms:edgeOptions')
86
+ || options.get('moz:firefoxOptions')
87
+ if (vendorOptions && vendorOptions.binary && vendorOptions.binary !== "") {
88
+ args.push("--browser-path", '"' + vendorOptions.binary + '"')
89
+ }
74
90
 
91
+ const smBinary = getBinary()
92
+ const spawnResult = spawnSync(smBinary, args)
93
+ let output
94
+ if (spawnResult.status) {
95
+ let errorMessage
96
+ if (spawnResult.stderr.toString()) {
97
+ errorMessage = spawnResult.stderr.toString()
98
+ }
99
+ if (spawnResult.stdout.toString()) {
100
+ try {
101
+ output = JSON.parse(spawnResult.stdout.toString())
102
+ errorMessage = output.result.message
103
+ } catch (e) {
104
+ errorMessage = e.toString()
105
+ }
106
+ }
107
+ throw new Error(`Error executing command for ${smBinary} with ${args}: ${errorMessage}`)
108
+ }
75
109
  try {
76
- output = JSON.parse(execSync(args.join(' ')).toString())
110
+ output = JSON.parse(spawnResult.stdout.toString())
77
111
  } catch (e) {
78
- let error
79
- try {
80
- error = JSON.parse(e.stdout.toString()).result.message
81
- } catch (e) {
82
- error = e.toString()
83
- }
84
- throw new Error(
85
- `Error executing command with ${args}: ${error}`
86
- )
112
+ throw new Error(`Error executing command for ${smBinary} with ${args}: ${e.toString()}`)
87
113
  }
88
114
 
89
- for (const key in output.logs){
115
+
116
+ for (const key in output.logs) {
90
117
  if (output.logs[key].level === 'WARN') {
91
118
  console.warn(`${output.logs[key].message}`)
92
119
  }
package/edge.js CHANGED
@@ -80,7 +80,6 @@
80
80
  const { Browser } = require('./lib/capabilities')
81
81
  const io = require('./io')
82
82
  const chromium = require('./chromium')
83
- const { driverLocation } = require('./common/seleniumManager')
84
83
 
85
84
  /**
86
85
  * Name of the EdgeDriver executable.
@@ -107,22 +106,6 @@ class ServiceBuilder extends chromium.ServiceBuilder {
107
106
  */
108
107
  constructor(opt_exe) {
109
108
  let exe = opt_exe || locateSynchronously()
110
-
111
- if (!exe) {
112
- try {
113
- exe = driverLocation('edge')
114
- } catch (err) {
115
- console.log(`Unable to obtain driver using Selenium Manager: ${err}`)
116
- }
117
- }
118
-
119
- if (!exe) {
120
- throw Error(
121
- `MSEdgeDriver could not be found on the PATH.
122
- For more information on how to install drivers see
123
- https://www.selenium.dev/documentation/webdriver/getting_started/install_drivers/.`
124
- )
125
- }
126
109
  super(exe)
127
110
  this.setLoopback(true)
128
111
  }
package/firefox.js CHANGED
@@ -127,7 +127,7 @@ const webdriver = require('./lib/webdriver')
127
127
  const zip = require('./io/zip')
128
128
  const { Browser, Capabilities } = require('./lib/capabilities')
129
129
  const { Zip } = require('./io/zip')
130
- const { driverLocation } = require('./common/seleniumManager')
130
+ const { getPath } = require('./common/driverFinder')
131
131
 
132
132
  /**
133
133
  * Thrown when there an add-on is malformed.
@@ -471,25 +471,7 @@ function locateSynchronously() {
471
471
  * @throws {Error}
472
472
  */
473
473
  function findGeckoDriver() {
474
- let exe = locateSynchronously()
475
-
476
- if (!exe) {
477
- try {
478
- exe = driverLocation(Browser.FIREFOX)
479
- } catch (err) {
480
- console.log(`Unable to obtain driver using Selenium Manager: ${err}`)
481
- }
482
- }
483
-
484
- if (!exe) {
485
- throw Error(
486
- `GeckoDriver could not be found on the PATH.
487
- For more information on how to install drivers see
488
- https://www.selenium.dev/documentation/webdriver/getting_started/install_drivers/.`
489
- )
490
- }
491
-
492
- return exe
474
+ return locateSynchronously()
493
475
  }
494
476
 
495
477
  /**
@@ -626,10 +608,16 @@ class Driver extends webdriver.WebDriver {
626
608
  executor = opt_executor
627
609
  configureExecutor(executor)
628
610
  } else if (opt_executor instanceof remote.DriverService) {
611
+ if (!opt_executor.getExecutable()) {
612
+ opt_executor.setExecutable(getPath(opt_executor, opt_config))
613
+ }
629
614
  executor = createExecutor(opt_executor.start())
630
615
  onQuit = () => opt_executor.kill()
631
616
  } else {
632
617
  let service = new ServiceBuilder().build()
618
+ if (!service.getExecutable()) {
619
+ service.setExecutable(getPath(service, opt_config))
620
+ }
633
621
  executor = createExecutor(service.start())
634
622
  onQuit = () => service.kill()
635
623
  }
package/http/index.js CHANGED
@@ -54,7 +54,8 @@ function getRequestOptions(aUrl) {
54
54
  options.search = null
55
55
  options.hash = null
56
56
  options.path = options.pathname
57
- options.hostname = options.hostname === 'localhost' ? '127.0.0.1' : options.hostname // To support Node 17 and above. Refer https://github.com/nodejs/node/issues/40702 for details.
57
+ options.hostname =
58
+ options.hostname === 'localhost' ? '127.0.0.1' : options.hostname // To support Node 17 and above. Refer https://github.com/nodejs/node/issues/40702 for details.
58
59
  return options
59
60
  }
60
61
 
package/ie.js CHANGED
@@ -35,7 +35,7 @@ const remote = require('./remote')
35
35
  const webdriver = require('./lib/webdriver')
36
36
  const { Browser, Capabilities } = require('./lib/capabilities')
37
37
  const error = require('./lib/error')
38
- const { driverLocation } = require('./common/seleniumManager')
38
+ const { getPath } = require('./common/driverFinder')
39
39
 
40
40
  const IEDRIVER_EXE = 'IEDriverServer.exe'
41
41
  const OPTIONS_CAPABILITY_KEY = 'se:ieOptions'
@@ -400,22 +400,6 @@ function createServiceFromCapabilities(capabilities) {
400
400
  }
401
401
 
402
402
  let exe = locateSynchronously()
403
- if (!exe) {
404
- try {
405
- exe = driverLocation('iexplorer')
406
- } catch (err) {
407
- console.log(`Unable to obtain driver using Selenium Manager: ${err}`)
408
- }
409
- }
410
-
411
- if (!exe || !fs.existsSync(exe)) {
412
- throw Error(
413
- `IEDriver could not be found on the PATH.
414
- For more information on how to install drivers see
415
- https://www.selenium.dev/documentation/webdriver/getting_started/install_drivers/.`
416
- )
417
- }
418
-
419
403
  var args = []
420
404
  if (capabilities.has(Key.HOST)) {
421
405
  args.push('--host=' + capabilities.get(Key.HOST))
@@ -482,6 +466,9 @@ class Driver extends webdriver.WebDriver {
482
466
  } else {
483
467
  service = createServiceFromCapabilities(options)
484
468
  }
469
+ if (!service.getExecutable()) {
470
+ service.setExecutable(getPath(service, options))
471
+ }
485
472
 
486
473
  let client = service.start().then((url) => new http.HttpClient(url))
487
474
  let executor = new http.Executor(client)
package/index.js CHANGED
@@ -41,6 +41,7 @@ const webdriver = require('./lib/webdriver')
41
41
  const select = require('./lib/select')
42
42
  const LogInspector = require('./bidi/logInspector')
43
43
  const BrowsingContext = require('./bidi/browsingContext')
44
+ const ScriptManager = require('./bidi/scriptManager')
44
45
 
45
46
  const Browser = capabilities.Browser
46
47
  const Capabilities = capabilities.Capabilities
@@ -799,3 +800,4 @@ exports.until = until
799
800
  exports.Select = select.Select
800
801
  exports.LogInspector = LogInspector
801
802
  exports.BrowsingContext = BrowsingContext
803
+ exports.ScriptManager = ScriptManager