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

refactor!: Migrate to Selenium 4 #1531

Merged
merged 4 commits into from
Oct 21, 2021

Conversation

valfirst
Copy link
Collaborator

@valfirst valfirst commented Oct 13, 2021

Change list

Migrate to Selenium 4

Types of changes

What types of changes are you proposing/introducing to Java client?

  • No changes in production code.
  • Bugfix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)

Details

BREAKING CHANGE:

  • interface io.appium.java_client.MobileDriver do not extend org.openqa.selenium.internal.FindsByClassName, org.openqa.selenium.internal.FindsByCssSelector, org.openqa.selenium.internal.FindsById, org.openqa.selenium.internal.FindsByLinkText, org.openqa.selenium.internal.FindsByName, org.openqa.selenium.internal.FindsByTagName, org.openqa.selenium.internal.FindsByXPath interfaces anymore because they were removed in Selenium Java client;
  • class io.appium.java_client.DefaultGenericMobileElement do not implement org.openqa.selenium.internal.FindsByClassName, org.openqa.selenium.internal.FindsByCssSelector, org.openqa.selenium.internal.FindsById, org.openqa.selenium.internal.FindsByLinkText, org.openqa.selenium.internal.FindsByName, org.openqa.selenium.internal.FindsByTagName, org.openqa.selenium.internal.FindsByXPath interfaces anymore because they were removed in Selenium Java client;
  • method String io.appium.java_client.remote.MobileOptions#getPlatformName() is removed in favor of Platform org.openqa.selenium.Capabilities#getPlatformName()
  • method io.appium.java_client.service.local.AppiumServiceBuilder#withStartUpTimeOut is removed in favor of org.openqa.selenium.remote.service.DriverService.Builder#withTimeout
  • drop Appium FindsBy* iterfaces in the same way it was done in Selenium java client. The removed intefraces are: io.appium.java_client.FindsByAccessibilityId, io.appium.java_client.FindsByAndroidDataMatcher, io.appium.java_client.FindsByAndroidUIAutomator, io.appium.java_client.FindsByAndroidViewMatcher, io.appium.java_client.FindsByAndroidViewTag, io.appium.java_client.FindsByCustom, io.appium.java_client.FindsByFluentSelector, io.appium.java_client.FindsByImage, io.appium.java_client.FindsByIosClassChain, io.appium.java_client.FindsByIosNSPredicate, io.appium.java_client.FindsByWindowsAutomation, io.appium.java_client.mac.FindsByClassChain, io.appium.java_client.mac.FindsByNsPredicate
  • remove methods findElements(String by, String using) and findElement(String by, String using) from io.appium.java_client.DefaultGenericMobileDriver and io.appium.java_client.DefaultGenericMobileElement because the originals of these methods are deprecated in Selenium RemoteWebDriver and RemoteWebElement and throw UnsupportedOperationException
  • remove io.appium.java_client.MobileSelector as it's used once, the string values from the enum are inlined in io.appium.java_client.MobileBy.java
  • drop deprecated method io.appium.java_client.AppiumDriver#substituteMobilePlatform

BUG FIXES:

Closes #1536
Closes #1273
Closes #1245

@linux-foundation-easycla
Copy link

linux-foundation-easycla bot commented Oct 13, 2021

CLA Signed

The committers are authorized under a signed CLA.

@valfirst valfirst marked this pull request as draft October 13, 2021 14:24
@valfirst valfirst mentioned this pull request Oct 13, 2021
4 tasks
return new HttpClient() {
@Override
public HttpResponse execute(HttpRequest request) {
request.setHeader(IDEMPOTENCY_KEY_HEADER, UUID.randomUUID().toString().toLowerCase());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍🏽

This comment was marked as off-topic.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can also implement a Filter to add the header if it's missing. That avoids the need for subclassing the httpclient

@mykola-mokhnach mykola-mokhnach changed the title Migrate to Selenium 4 refactor!: Migrate to Selenium 4 Oct 13, 2021
@mykola-mokhnach
Copy link
Contributor

Please mention all breaking changes in the commit message according to conventional commits rules.

@mykola-mokhnach
Copy link
Contributor

I'd like to establish a better connection between Appium and Selenium, thus kindly asking @shs96c to take a look at this PR and help us to optimize it better before we advertise the compatibility with Selenium4 and release a major lib update.

@appium appium temporarily blocked BOYKHMER Oct 13, 2021
@valfirst valfirst force-pushed the migrate-to-selenium-4 branch 2 times, most recently from 27bdc96 to 0be6ac3 Compare October 13, 2021 18:36
@titusfortner
Copy link
Contributor

Would it make sense to remove/deprecate the Appium FindsElementBy* methods, so both Appium and Selenium are solely using the By.* and MobileBy.* approach?

@titusfortner
Copy link
Contributor

Also, for what it's worth, @shs96c is going to be stepping down from Selenium project in a couple weeks. I don't know if he will or won't have the chance to review this before he departs, but as a Selenium dev, I would like to help facilitate our projects working together more going forward. It would be great if our users had a more seamless experience using both of our projects in each of the languages.

@SrinivasanTarget
Copy link
Member

Would it make sense to remove/deprecate the Appium FindsElementBy* methods, so both Appium and Selenium are solely using the By.* and MobileBy.* approach?

Agree. I think it's right time to get rid of it and keep it inline with Se4 way.

@@ -21,14 +21,15 @@
import org.openqa.selenium.logging.Logs;
Copy link
Contributor

@mykola-mokhnach mykola-mokhnach Oct 14, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not sure how much it would be possible now, but I'd really like to get rid of the package override in the client (e.g. remove everything under src/main/java/org/openqa/selenium from this lib)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Split packages are forbidden in Java 9+. Anything that uses the module system will refuse to load one.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not clear why this is being done. Perhaps with a better understanding of that, we can figure out a way to solve the problem that doesn't create a split package?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe this was done to "override" some Selenium interfaces, so Appium could create elements inherited from WebElement (e.g. AppiumElement). See SeleniumHQ/selenium#415 (which has never been merged) for more detalis.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for now I don't see any elegant way to fix this package override, if anyone has ideas, please share

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This topic is currently being discussed with @shs96c
Perhaps, we could find a happy middle there before the next major release (ofc not necessarily as part of this PR, but this might still be a breaking change)
Feel free to follow the discussion https://seleniumhq.slack.com/archives/CBH302726/p1634562817364100

@shs96c
Copy link
Contributor

shs96c commented Oct 15, 2021

In response to #1531 (comment), I'll certainly do my best to review this PR.

Copy link
Contributor

@shs96c shs96c left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems pretty much like we expected the migration to look. One question about the split package

return new HttpClient() {
@Override
public HttpResponse execute(HttpRequest request) {
request.setHeader(IDEMPOTENCY_KEY_HEADER, UUID.randomUUID().toString().toLowerCase());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can also implement a Filter to add the header if it's missing. That avoids the need for subclassing the httpclient

.build();
client.newWebSocket(request, this);
client.dispatcher().executorService().shutdown();
ClientConfig clientConfig = ClientConfig.defaultConfig().readTimeout(Duration.ZERO);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I really hope that this disables the read timeout....

@@ -21,14 +21,15 @@
import org.openqa.selenium.logging.Logs;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Split packages are forbidden in Java 9+. Anything that uses the module system will refuse to load one.

@@ -21,14 +21,15 @@
import org.openqa.selenium.logging.Logs;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not clear why this is being done. Perhaps with a better understanding of that, we can figure out a way to solve the problem that doesn't create a split package?

@valfirst
Copy link
Collaborator Author

It's not clear why this is being done. Perhaps with a better understanding of that, we can figure out a way to solve the problem that doesn't create a split package?

@shs96c I think the answer is here: d28c76d

@mykola-mokhnach
Copy link
Contributor

In response to #1531 (comment), I'll certainly do my best to review this PR.

Thank you Simon. We really appreciate your help

@valfirst
Copy link
Collaborator Author

SeleniumHQ/selenium@0aaa401#r58091435 - this change breaks the tests, I'm not sure whether it's expected and whether it worths fixing on Appium Java client side (e.g. by introducing MobileBy.className)

BREAKING CHANGE:
- interface `io.appium.java_client.MobileDriver` do not extend `org.openqa.selenium.internal.FindsByClassName`, `org.openqa.selenium.internal.FindsByCssSelector`, `org.openqa.selenium.internal.FindsById`, `org.openqa.selenium.internal.FindsByLinkText`, `org.openqa.selenium.internal.FindsByName`, `org.openqa.selenium.internal.FindsByTagName`, `org.openqa.selenium.internal.FindsByXPath` interfaces anymore because they were removed in Selenium Java client;
- class `io.appium.java_client.DefaultGenericMobileElement` do not implement `org.openqa.selenium.internal.FindsByClassName`, `org.openqa.selenium.internal.FindsByCssSelector`, `org.openqa.selenium.internal.FindsById`, `org.openqa.selenium.internal.FindsByLinkText`, `org.openqa.selenium.internal.FindsByName`, `org.openqa.selenium.internal.FindsByTagName`, `org.openqa.selenium.internal.FindsByXPath` interfaces anymore because they were removed in Selenium Java client;
- method `String io.appium.java_client.remote.MobileOptions#getPlatformName()` is removed in favor of `Platform org.openqa.selenium.Capabilities#getPlatformName()`
- method `io.appium.java_client.service.local.AppiumServiceBuilder#withStartUpTimeOut` is removed in favor of `org.openqa.selenium.remote.service.DriverService.Builder#withTimeout`
@valfirst valfirst force-pushed the migrate-to-selenium-4 branch 2 times, most recently from ae6ea41 to f1579d6 Compare October 19, 2021 12:00
BREAKING CHANGE:
- drop Appium `FindsBy*` iterfaces in the same way it was done in Selenium java client. The removed intefraces are: `io.appium.java_client.FindsByAccessibilityId`, `io.appium.java_client.FindsByAndroidDataMatcher`, `io.appium.java_client.FindsByAndroidUIAutomator`,  `io.appium.java_client.FindsByAndroidViewMatcher`, `io.appium.java_client.FindsByAndroidViewTag`, `io.appium.java_client.FindsByCustom`, `io.appium.java_client.FindsByFluentSelector`, `io.appium.java_client.FindsByImage`, `io.appium.java_client.FindsByIosClassChain`, `io.appium.java_client.FindsByIosNSPredicate`, `io.appium.java_client.FindsByWindowsAutomation`, `io.appium.java_client.mac.FindsByClassChain`, `io.appium.java_client.mac.FindsByNsPredicate`
- remove methods `findElements(String by, String using)` and `findElement(String by, String using)` from `io.appium.java_client.DefaultGenericMobileDriver` and `io.appium.java_client.DefaultGenericMobileElement` because the originals of these methods are deprecated in Selenium `RemoteWebDriver` and `RemoteWebElement` and throw `UnsupportedOperationException`
- remove `io.appium.java_client.MobileSelector` as it's used once, the string values from the enum are inlined in `io.appium.java_client.MobileBy.java`
The change made in Selenium 4 (SeleniumHQ/selenium@0aaa401#r58091435)
broke Appium `class name` selector strategy. The workaround was implemented: `MobileBy#className`.
…orm`

BREAKING CHANGE: drop deprecated method `io.appium.java_client.AppiumDriver#substituteMobilePlatform`
@valfirst valfirst marked this pull request as ready for review October 20, 2021 18:53
throw formIllegalArgumentException(contextClass, FindsByAndroidViewTag.class,
FindsByFluentSelector.class);
@Override public String toString() {
return "By.AndroidViewTag: " + getLocatorString();
Copy link
Contributor

@mykola-mokhnach mykola-mokhnach Oct 20, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we just define toString in the base class and make it to something like

return String.format("By.%s: %s", getClass().getSimpleName(), getLocatorString())

?

Copy link
Contributor

@mykola-mokhnach mykola-mokhnach left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nicely done. Thanks Valery

Copy link
Member

@SrinivasanTarget SrinivasanTarget left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good. Thanks @valfirst

@@ -7,4 +7,4 @@ signing.secretKeyRingFile=PathToYourKeyRingFile
ossrhUsername=your-jira-id
ossrhPassword=your-jira-password

selenium.version=3.141.59
selenium.version=4.0.0-rc-3
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's update to stable version as it's out now

@SrinivasanTarget SrinivasanTarget merged commit 8057ac6 into appium:master Oct 21, 2021
sakibguy added a commit to sakibguy/java-client that referenced this pull request Oct 21, 2021
refactor!: Migrate to Selenium 4 (appium#1531)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
6 participants