Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: update selenium atoms based on selenium 4.11.0 #268

Merged
merged 1 commit into from
Aug 16, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,11 @@ do so, simply update the branch in the `scripts/common.js`, by modifying the `SE
constant at the top of the file. Then run `npm run build:atoms`, test and create
a pull request with the resulting changed atoms directory.

Note that to build the atoms it is required that you have the `bazel` tool installed. Selenium will
also require that it be installed at a particular version relative to the version of Selenium that
has been checked out by our build script. It is most convenient simply to install
[`bazelisk`](https://github.com/bazelbuild/bazelisk) and have it available on your PATH.

One caveat is that there are some changes that are needed for Appium, that are
not yet in the Selenium codebase. See the [atoms notes](./atoms-notes.md) for
details.
Expand Down
92 changes: 7 additions & 85 deletions atoms-notes.md
Original file line number Diff line number Diff line change
@@ -1,89 +1,11 @@
## Atom notes

The Selenium atoms can generally be used without change. Two changes are needed
in order to maintain current functionality in the mobile context.
Until the following PRs are merged and published, building the atoms requires patching the tmp
Selenium checkout in this repo with the change listed in the PR (otherwise certain fragments will
get deleted on build).

### React input operation
- https://github.com/SeleniumHQ/selenium/pull/12532
- https://github.com/SeleniumHQ/selenium/pull/12555
- https://github.com/SeleniumHQ/selenium/pull/12557

React manages the content of input elements, and reverts changes that it did
not handle itself. This means any direct call to `element.value` will be reverted
by React. To get around this, bypass the React `value` function and work directly
with the `HTMLInputElement`. This will still trigger all the React event handling
apparatus.
```diff
--- a/javascript/atoms/keyboard.js
+++ b/javascript/atoms/keyboard.js
@@ -605,12 +605,19 @@ bot.Keyboard.prototype.updateOnCharacter_ = function(key) {

var character = this.getChar_(key);
var newPos = goog.dom.selection.getStart(this.getElement()) + 1;
- if (bot.Keyboard.supportsSelection(this.getElement())) {
+
+ // for react support, if this is an input element then skip any added value setters
+ // otherwise the input will not get past the react change handlers
+ if (this.getElement() instanceof window.HTMLInputElement) {
+ var valueAccessor = Object.getOwnPropertyDescriptor(window.HTMLInputElement.prototype, 'value');
+ var value = valueAccessor.get.call(/** @type {window.HTMLInputElement} */ (this.getElement()));
+ valueAccessor.set.call(/** @type {window.HTMLInputElement} */ (this.getElement()), value + character);
+ } else if (bot.Keyboard.supportsSelection(this.getElement())) {
goog.dom.selection.setText(this.getElement(), character);
- goog.dom.selection.setStart(this.getElement(), newPos);
} else {
this.getElement().value += character;
}
+
if (goog.userAgent.WEBKIT) {
this.fireHtmlEvent(bot.events.EventType.TEXTINPUT);
}
```


### Shadow DOM handling

Support for Shadow DOM elements. This is needed until https://github.com/SeleniumHQ/selenium/pull/7808
is merged and published.
```diff
--- a/javascript/atoms/inject.js
+++ b/javascript/atoms/inject.js
@@ -524,6 +524,9 @@ bot.inject.cache.getElement = function(key, opt_doc) {
if (node == doc.documentElement) {
return el;
}
+ if (node.host && node.nodeType === 11) {
+ node = node.host;
+ }
node = node.parentNode;
}
delete cache[key];
```


### Circular reference handling

Shadow DOM elements can be reported multiple times, which leads to an error
for "recursive object" references.

```diff
--- a/javascript/atoms/inject.js
+++ b/javascript/atoms/inject.js
@@ -100,6 +100,7 @@ bot.inject.WINDOW_KEY = 'WINDOW';
* @see https://github.com/SeleniumHQ/selenium/wiki/JsonWireProtocol
*/
bot.inject.wrapValue = function(value) {
+ var parentIsShadow = value instanceof ShadowRoot;
var _wrap = function(value, seen) {
switch (goog.typeOf(value)) {
case 'string':
@@ -121,6 +122,11 @@ bot.inject.wrapValue = function(value) {
// a ton of compiler warnings.
value = /**@type {!Object}*/ (value);
if (seen.indexOf(value) >= 0) {
+ if (parentIsShadow) {
+ // elements get reported multiple times in shadow elements,
+ // so ignore reported circularity
+ return null;
+ }
throw new bot.Error(bot.ErrorCode.JAVASCRIPT_ERROR,
'Recursive object cannot be transferred');
}
```
When these PRs are merged and our Selenium version updated to match, we can delete this note!
109 changes: 50 additions & 59 deletions atoms/active_element.js
100644 → 100755

Large diffs are not rendered by default.

Loading