selenium-webdriver 4.18.1 → 4.19.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,79 @@
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 { SameSite, BytesValue } = require('./networkTypes')
19
+
20
+ class CookieFilter {
21
+ #map = new Map()
22
+
23
+ name(name) {
24
+ this.#map.set('name', name)
25
+ return this
26
+ }
27
+
28
+ value(value) {
29
+ if (!(value instanceof BytesValue)) {
30
+ throw new Error(`Value must be an instance of BytesValue. Received:'${value}'`)
31
+ }
32
+ this.#map.set('value', Object.fromEntries(value.asMap()))
33
+ return this
34
+ }
35
+
36
+ domain(domain) {
37
+ this.#map.set('domain', domain)
38
+ return this
39
+ }
40
+
41
+ path(path) {
42
+ this.#map.set('path', path)
43
+ return this
44
+ }
45
+
46
+ size(size) {
47
+ this.#map.set('size', size)
48
+ return this
49
+ }
50
+
51
+ httpOnly(httpOnly) {
52
+ this.#map.set('httpOnly', httpOnly)
53
+ return this
54
+ }
55
+
56
+ secure(secure) {
57
+ this.#map.set('secure', secure)
58
+ return this
59
+ }
60
+
61
+ sameSite(sameSite) {
62
+ if (!(sameSite instanceof SameSite)) {
63
+ throw new Error(`Params must be a value in SameSite. Received:'${sameSite}'`)
64
+ }
65
+ this.#map.set('sameSite', sameSite)
66
+ return this
67
+ }
68
+
69
+ expiry(expiry) {
70
+ this.#map.set('expiry', expiry)
71
+ return this
72
+ }
73
+
74
+ asMap() {
75
+ return this.#map
76
+ }
77
+ }
78
+
79
+ module.exports = { CookieFilter }
package/bidi/index.js CHANGED
@@ -40,6 +40,31 @@ class Index extends EventEmitter {
40
40
  })
41
41
  }
42
42
 
43
+ /**
44
+ * @returns {WebSocket}
45
+ */
46
+ get socket() {
47
+ return this._ws
48
+ }
49
+
50
+ /**
51
+ * @returns {boolean|*}
52
+ */
53
+ get isConnected() {
54
+ return this.connected
55
+ }
56
+
57
+ /**
58
+ * Get Bidi Status
59
+ * @returns {Promise<*>}
60
+ */
61
+ get status() {
62
+ return this.send({
63
+ method: 'session.status',
64
+ params: {},
65
+ })
66
+ }
67
+
43
68
  /**
44
69
  * Resolve connection
45
70
  * @returns {Promise<unknown>}
@@ -56,20 +81,6 @@ class Index extends EventEmitter {
56
81
  })
57
82
  }
58
83
 
59
- /**
60
- * @returns {WebSocket}
61
- */
62
- get socket() {
63
- return this._ws
64
- }
65
-
66
- /**
67
- * @returns {boolean|*}
68
- */
69
- get isConnected() {
70
- return this.connected
71
- }
72
-
73
84
  /**
74
85
  * Sends a bidi request
75
86
  * @param params
@@ -183,17 +194,6 @@ class Index extends EventEmitter {
183
194
  await this.send(params)
184
195
  }
185
196
 
186
- /**
187
- * Get Bidi Status
188
- * @returns {Promise<*>}
189
- */
190
- get status() {
191
- return this.send({
192
- method: 'session.status',
193
- params: {},
194
- })
195
- }
196
-
197
197
  /**
198
198
  * Close ws connection.
199
199
  * @returns {Promise<unknown>}
package/bidi/input.js CHANGED
@@ -18,6 +18,7 @@
18
18
  // type: module added to package.json
19
19
  // import { WebElement } from '../lib/webdriver'
20
20
  const { WebElement } = require('../lib/webdriver')
21
+ const { RemoteReferenceType, ReferenceValue } = require('./protocolValue')
21
22
 
22
23
  class Input {
23
24
  constructor(driver) {
@@ -57,6 +58,25 @@ class Input {
57
58
  }
58
59
  return await this.bidi.send(command)
59
60
  }
61
+
62
+ async setFiles(browsingContextId, element, files) {
63
+ if (typeof element !== 'string' && !(element instanceof ReferenceValue)) {
64
+ throw Error(`Pass in a WebElement id as a string or a ReferenceValue. Received: ${element}`)
65
+ }
66
+
67
+ const command = {
68
+ method: 'input.setFiles',
69
+ params: {
70
+ context: browsingContextId,
71
+ element:
72
+ typeof element === 'string'
73
+ ? new ReferenceValue(RemoteReferenceType.SHARED_ID, element).asMap()
74
+ : element.asMap(),
75
+ files: typeof files === 'string' ? [files] : files,
76
+ },
77
+ }
78
+ await this.bidi.send(command)
79
+ }
60
80
  }
61
81
 
62
82
  async function updateActions(actions) {
@@ -21,4 +21,4 @@ const InterceptPhase = {
21
21
  AUTH_REQUIRED: 'authRequired',
22
22
  }
23
23
 
24
- module.exports = {InterceptPhase}
24
+ module.exports = { InterceptPhase }
package/bidi/network.js CHANGED
@@ -15,8 +15,11 @@
15
15
  // specific language governing permissions and limitations
16
16
  // under the License.
17
17
 
18
- const { BeforeRequestSent, ResponseStarted, FetchError} = require('./networkTypes')
19
- const {AddInterceptParameters} = require("./addInterceptParameters");
18
+ const { BeforeRequestSent, ResponseStarted, FetchError } = require('./networkTypes')
19
+ const { AddInterceptParameters } = require('./addInterceptParameters')
20
+ const { ContinueResponseParameters } = require('./continueResponseParameters')
21
+ const { ContinueRequestParameters } = require('./continueRequestParameters')
22
+ const { ProvideResponseParameters } = require('./provideResponseParameters')
20
23
 
21
24
  class Network {
22
25
  constructor(driver, browsingContextIds) {
@@ -92,19 +95,18 @@ class Network {
92
95
  )
93
96
  }
94
97
  callback(response)
95
- }
98
+ }
96
99
  })
97
100
  }
98
101
 
99
102
  async addIntercept(params) {
100
-
101
- if (!params instanceof AddInterceptParameters) {
102
- throw new Error(`Params must be an instance of AddInterceptParamenters. Received:'${params}'`)
103
+ if (!(params instanceof AddInterceptParameters)) {
104
+ throw new Error(`Params must be an instance of AddInterceptParameters. Received:'${params}'`)
103
105
  }
104
106
 
105
107
  const command = {
106
108
  method: 'network.addIntercept',
107
- params: Object.fromEntries(params.asMap())
109
+ params: Object.fromEntries(params.asMap()),
108
110
  }
109
111
 
110
112
  let response = await this.bidi.send(command)
@@ -115,7 +117,7 @@ class Network {
115
117
  async removeIntercept(interceptId) {
116
118
  const command = {
117
119
  method: 'network.removeIntercept',
118
- params: {intercept: interceptId},
120
+ params: { intercept: interceptId },
119
121
  }
120
122
 
121
123
  await this.bidi.send(command)
@@ -123,17 +125,27 @@ class Network {
123
125
 
124
126
  async continueWithAuth(requestId, username, password) {
125
127
  const command = {
126
- method: 'network.continueWithAuth',
127
- params: {
128
- request: requestId.toString(),
129
- action: 'provideCredentials',
130
- credentials: {
131
- type: 'password',
132
- username: username,
133
- password: password
134
- },
135
- },
136
- }
128
+ method: 'network.continueWithAuth',
129
+ params: {
130
+ request: requestId.toString(),
131
+ action: 'provideCredentials',
132
+ credentials: {
133
+ type: 'password',
134
+ username: username,
135
+ password: password,
136
+ },
137
+ },
138
+ }
139
+ await this.bidi.send(command)
140
+ }
141
+
142
+ async failRequest(requestId) {
143
+ const command = {
144
+ method: 'network.failRequest',
145
+ params: {
146
+ request: requestId.toString(),
147
+ },
148
+ }
137
149
  await this.bidi.send(command)
138
150
  }
139
151
 
@@ -142,7 +154,7 @@ class Network {
142
154
  method: 'network.continueWithAuth',
143
155
  params: {
144
156
  request: requestId.toString(),
145
- action: 'default'
157
+ action: 'default',
146
158
  },
147
159
  }
148
160
  await this.bidi.send(command)
@@ -153,20 +165,59 @@ class Network {
153
165
  method: 'network.continueWithAuth',
154
166
  params: {
155
167
  request: requestId.toString(),
156
- action: 'cancel'
168
+ action: 'cancel',
157
169
  },
158
170
  }
159
171
  await this.bidi.send(command)
160
172
  }
161
173
 
174
+ async continueRequest(params) {
175
+ if (!(params instanceof ContinueRequestParameters)) {
176
+ throw new Error(`Params must be an instance of ContinueRequestParameters. Received:'${params}'`)
177
+ }
178
+
179
+ const command = {
180
+ method: 'network.continueRequest',
181
+ params: Object.fromEntries(params.asMap()),
182
+ }
183
+
184
+ await this.bidi.send(command)
185
+ }
186
+
187
+ async continueResponse(params) {
188
+ if (!(params instanceof ContinueResponseParameters)) {
189
+ throw new Error(`Params must be an instance of ContinueResponseParameters. Received:'${params}'`)
190
+ }
191
+
192
+ const command = {
193
+ method: 'network.continueResponse',
194
+ params: Object.fromEntries(params.asMap()),
195
+ }
196
+
197
+ await this.bidi.send(command)
198
+ }
199
+
200
+ async provideResponse(params) {
201
+ if (!(params instanceof ProvideResponseParameters)) {
202
+ throw new Error(`Params must be an instance of ProvideResponseParameters. Received:'${params}'`)
203
+ }
204
+
205
+ const command = {
206
+ method: 'network.provideResponse',
207
+ params: Object.fromEntries(params.asMap()),
208
+ }
209
+
210
+ await this.bidi.send(command)
211
+ }
212
+
162
213
  async close() {
163
214
  await this.bidi.unsubscribe(
164
215
  'network.beforeRequestSent',
165
216
  'network.responseStarted',
166
217
  'network.responseCompleted',
167
- 'network.authRequired')
218
+ 'network.authRequired',
219
+ )
168
220
  }
169
-
170
221
  }
171
222
 
172
223
  async function getNetworkInstance(driver, browsingContextIds = null) {
@@ -17,11 +17,54 @@
17
17
 
18
18
  const { NavigationInfo } = require('./browsingContextTypes')
19
19
 
20
+ const SameSite = {
21
+ STRICT: 'strict',
22
+ LAX: 'lax',
23
+ NONE: 'none',
24
+
25
+ findByName(name) {
26
+ return (
27
+ Object.values(this).find((type) => {
28
+ return typeof type === 'string' && name.toLowerCase() === type.toLowerCase()
29
+ }) || null
30
+ )
31
+ },
32
+ }
33
+
34
+ class BytesValue {
35
+ static Type = {
36
+ STRING: 'string',
37
+ BASE64: 'base64',
38
+ }
39
+
40
+ constructor(type, value) {
41
+ this._type = type
42
+ this._value = value
43
+ }
44
+
45
+ get type() {
46
+ return this._type
47
+ }
48
+
49
+ get value() {
50
+ return this._value
51
+ }
52
+
53
+ asMap() {
54
+ const map = new Map()
55
+ map.set('type', this._type)
56
+ map.set('value', this._value)
57
+ return map
58
+ }
59
+ }
60
+
20
61
  class Header {
21
- constructor(name, value, binaryValue) {
62
+ constructor(name, value) {
22
63
  this._name = name
64
+ if (!(value instanceof BytesValue)) {
65
+ throw new Error(`Value must be an instance of BytesValue. Received:'${value}'`)
66
+ }
23
67
  this._value = value
24
- this._binaryValue = binaryValue
25
68
  }
26
69
 
27
70
  get name() {
@@ -31,17 +74,12 @@ class Header {
31
74
  get value() {
32
75
  return this._value
33
76
  }
34
-
35
- get binaryValue() {
36
- return this._binaryValue
37
- }
38
77
  }
39
78
 
40
79
  class Cookie {
41
- constructor(name, value, binaryValue, domain, path, expires, size, httpOnly, secure, sameSite) {
80
+ constructor(name, value, domain, path, size, httpOnly, secure, sameSite, expires) {
42
81
  this._name = name
43
82
  this._value = value
44
- this._binaryValue = binaryValue
45
83
  this._domain = domain
46
84
  this._path = path
47
85
  this._expires = expires
@@ -59,10 +97,6 @@ class Cookie {
59
97
  return this._value
60
98
  }
61
99
 
62
- get binaryValue() {
63
- return this._binaryValue
64
- }
65
-
66
100
  get domain() {
67
101
  return this._domain
68
102
  }
@@ -186,9 +220,8 @@ class RequestData {
186
220
  headers.forEach((header) => {
187
221
  let name = header.name
188
222
  let value = 'value' in header ? header.value : null
189
- let binaryValue = 'binaryValue' in header ? header.binaryValue : null
190
223
 
191
- this._headers.push(new Header(name, value, binaryValue))
224
+ this._headers.push(new Header(name, new BytesValue(value.type, value.value)))
192
225
  })
193
226
 
194
227
  this._cookies = []
@@ -201,10 +234,9 @@ class RequestData {
201
234
  let secure = cookie.secure
202
235
  let sameSite = cookie.sameSite
203
236
  let value = 'value' in cookie ? cookie.value : null
204
- let binaryValue = 'binaryValue' in cookie ? cookie.binaryValue : null
205
237
  let expires = 'expires' in cookie ? cookie.expires : null
206
238
 
207
- this._cookies.push(new Cookie(name, value, binaryValue, domain, path, expires, size, httpOnly, secure, sameSite))
239
+ this._cookies.push(new Cookie(name, value, domain, path, size, httpOnly, secure, sameSite, expires))
208
240
  })
209
241
  this._headersSize = headersSize
210
242
  this._bodySize = bodySize
@@ -453,4 +485,4 @@ class ResponseStarted extends BaseParameters {
453
485
  }
454
486
  }
455
487
 
456
- module.exports = { BeforeRequestSent, ResponseStarted, FetchError }
488
+ module.exports = { Header, BytesValue, Cookie, SameSite, BeforeRequestSent, ResponseStarted, FetchError }
@@ -0,0 +1,67 @@
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 { BytesValue } = require('./networkTypes')
19
+
20
+ class PartialCookie {
21
+ #map = new Map()
22
+
23
+ constructor(name, value, domain) {
24
+ this.#map.set('name', name)
25
+ if (!(value instanceof BytesValue)) {
26
+ throw new Error(`Value must be an instance of BytesValue. Received:'${value}'`)
27
+ }
28
+ this.#map.set('value', Object.fromEntries(value.asMap()))
29
+ this.#map.set('domain', domain)
30
+ }
31
+
32
+ path(path) {
33
+ this.#map.set('path', path)
34
+ return this
35
+ }
36
+
37
+ size(size) {
38
+ this.#map.set('size', size)
39
+ return this
40
+ }
41
+
42
+ httpOnly(httpOnly) {
43
+ this.#map.set('httpOnly', httpOnly)
44
+ return this
45
+ }
46
+
47
+ secure(secure) {
48
+ this.#map.set('secure', secure)
49
+ return this
50
+ }
51
+
52
+ sameSite(sameSite) {
53
+ this.#map.set('sameSite', sameSite)
54
+ return this
55
+ }
56
+
57
+ expiry(expiry) {
58
+ this.#map.set('expiry', expiry)
59
+ return this
60
+ }
61
+
62
+ asMap() {
63
+ return this.#map
64
+ }
65
+ }
66
+
67
+ module.exports = { PartialCookie }
@@ -0,0 +1,69 @@
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 Type = {
19
+ CONTEXT: 'context',
20
+ STORAGE_KEY: 'storageKey',
21
+ }
22
+
23
+ class PartitionDescriptor {
24
+ #type
25
+
26
+ constructor(type) {
27
+ this.#type = type
28
+ }
29
+ }
30
+
31
+ class BrowsingContextPartitionDescriptor extends PartitionDescriptor {
32
+ #context = null
33
+
34
+ constructor(context) {
35
+ super(Type.CONTEXT)
36
+ this.#context = context
37
+ }
38
+
39
+ asMap() {
40
+ const map = new Map()
41
+ map.set('type', Type.CONTEXT)
42
+ map.set('context', this.#context)
43
+ return map
44
+ }
45
+ }
46
+
47
+ class StorageKeyPartitionDescriptor extends PartitionDescriptor {
48
+ #map = new Map()
49
+
50
+ constructor() {
51
+ super(Type.STORAGE_KEY)
52
+ }
53
+
54
+ userContext(userContext) {
55
+ this.#map.set('userContext', userContext)
56
+ return this
57
+ }
58
+
59
+ sourceOrigin(sourceOrigin) {
60
+ this.#map.set('sourceOrigin', sourceOrigin)
61
+ return this
62
+ }
63
+
64
+ asMap() {
65
+ return this.#map
66
+ }
67
+ }
68
+
69
+ module.exports = { BrowsingContextPartitionDescriptor, StorageKeyPartitionDescriptor }
@@ -0,0 +1,36 @@
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
+ class PartitionKey {
19
+ #userContext
20
+ #sourceOrigin
21
+
22
+ constructor(userContext, sourceOrigin) {
23
+ this.#userContext = userContext
24
+ this.#sourceOrigin = sourceOrigin
25
+ }
26
+
27
+ get userContext() {
28
+ return this.#userContext
29
+ }
30
+
31
+ get sourceOrigin() {
32
+ return this.#sourceOrigin
33
+ }
34
+ }
35
+
36
+ module.exports = { PartitionKey }
@@ -160,23 +160,27 @@ class RemoteValue {
160
160
  }
161
161
 
162
162
  class ReferenceValue {
163
+ #handle
164
+ #sharedId
163
165
  constructor(handle, sharedId) {
164
166
  if (handle === RemoteReferenceType.HANDLE) {
165
- this.handle = sharedId
167
+ this.#handle = sharedId
168
+ } else if (handle === RemoteReferenceType.SHARED_ID) {
169
+ this.#sharedId = sharedId
166
170
  } else {
167
- this.handle = handle
168
- this.sharedId = sharedId
171
+ this.#handle = handle
172
+ this.#sharedId = sharedId
169
173
  }
170
174
  }
171
175
 
172
176
  asMap() {
173
177
  const toReturn = {}
174
- if (this.handle != null) {
175
- toReturn[RemoteReferenceType.HANDLE] = this.handle
178
+ if (this.#handle != null) {
179
+ toReturn[RemoteReferenceType.HANDLE] = this.#handle
176
180
  }
177
181
 
178
- if (this.sharedId != null) {
179
- toReturn[RemoteReferenceType.SHARED_ID] = this.sharedId
182
+ if (this.#sharedId != null) {
183
+ toReturn[RemoteReferenceType.SHARED_ID] = this.#sharedId
180
184
  }
181
185
 
182
186
  return toReturn