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

Fix visible commands for Appium. #3566

Merged
merged 10 commits into from Feb 9, 2023
Merged

Conversation

garg3133
Copy link
Member

Fixes: #3523

@garg3133
Copy link
Member Author

This PR does not consider BrowserStack App Automate runs and thus, visible commands still fail over there.

@@ -52,6 +53,10 @@ class LocateElement {

const elementInstance = Element.createFromSelector(selector, strategy);

if (isAppiumClient && strategy === 'id') {
return new By(strategy, selector);
}
Copy link
Member Author

Choose a reason for hiding this comment

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

This change is for the following reason:

For waitForElementVisible command and expect.element().visible assertion, when we pass {selector: 'com.app:id/web-login', locateStrategy: 'id'} as selector, it gets modified to {using: 'css selector', value: '*[id="com\\.app\\:id\\/web-login"]' when searching for the element.

This fails in Appium v1.17.0 (default version of Appium in BrowserStack) since Appium v1.17.0 does not support css selector locate strategy, but works fine on the latest version of Appium 1.x.

So, I made this change to keep the locate strategy as id only when working with Appium.

@@ -367,7 +367,7 @@ module.exports = class MethodMappings {
},

async locateMultipleElements(element) {
const locator = Locator.create(element);
const locator = Locator.create(element, this.transport.api.isAppiumClient());
Copy link
Member

Choose a reason for hiding this comment

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

I suggest to create a subclass of Locator which overrides the create() method. That way we don't have to pass the isAppium flag around and pollute the Locator class.

Copy link
Member Author

Choose a reason for hiding this comment

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

Please check 42d08a7.

I couldn't think of any other good way of doing it, since I need all the functionality of LocateElement.create() method except just the last line where it converts {using: 'id', value: 'org.wikipedia:id/search_container'} to {using: 'css selector', value: '*[id="org\\.wikipedia\\:id\\/search_container"]'}.

Other way could be create a sub-class of By itself, but then we'd have to somehow pass the value of isAppiumClient into By class for that to work.

Copy link
Member

Choose a reason for hiding this comment

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

How about adding a Locator.createAppium(element) method?

Copy link
Member Author

Choose a reason for hiding this comment

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

Please check the implementation now. Also tested it by running .waitForElementVisible command on both Appium Client and normal desktop Chrome browser.


// Handle BrowserStack case
// (BrowserStack always returns platformName in capabilities)
const isMobile = this.__isPlatformName('android') || this.__isPlatformName('ios');
Copy link
Member

Choose a reason for hiding this comment

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

Use isMobile from utils

Copy link
Member Author

Choose a reason for hiding this comment

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

Cannot use isMobile from utils here because that method only considers desiredCapabilites whereas over here we need to check is android or ios is present as platformName inside the capabilities returned by BrowserStack.

This is necessary because users might not explicitly specify platformName in their desiredCapabilites (for example, when testing on mobile browser on BrowserStack, platformName in desired capabilites is not necessary) but BrowserStack would always send back the platformName in capabilities.

Copy link
Member Author

Choose a reason for hiding this comment

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

We would also need to tweek isAndroid() and isIOS() methods available in our API accordingly for it to consider capabilities as well, but that is out of scope of this PR and I'll create a separate issue for that.

Copy link
Member Author

Choose a reason for hiding this comment

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

Created an issue here: #3603

@@ -531,11 +531,14 @@ module.exports = class MethodMappings {
return `/element/${id}/location_in_view`;
},

async isElementDisplayed(webElementOrId) {
isElementDisplayed(webElementOrId) {
if (this.transport.api.isAppiumClient()) {
Copy link
Member

Choose a reason for hiding this comment

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

We should not use api methods here. We can move isAppium client to util and api method can use take use of that util function

Copy link
Member Author

Choose a reason for hiding this comment

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

Following up on the above response, this method cannot be moved to utils in its current form since for handling the BrowserStack case, we'd need the capabilities returned by BrowserStack after a session is established with it, and those capabilities are only made available in client.js as this.capabilities.

@beatfactor beatfactor merged commit 1e5b4d1 into nightwatchjs:main Feb 9, 2023
@garg3133 garg3133 deleted the appium-visible branch February 25, 2023 11:24
harshit-bs pushed a commit to harshit-bs/nightwatch that referenced this pull request Mar 16, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

assert does not work in native android app
4 participants