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

@AndroidFindBy and @iOSFindBy for native app automation #184

Closed
email2vimalraj opened this issue Apr 15, 2015 · 32 comments · Fixed by #213
Closed

@AndroidFindBy and @iOSFindBy for native app automation #184

email2vimalraj opened this issue Apr 15, 2015 · 32 comments · Fixed by #213

Comments

@email2vimalraj
Copy link
Contributor

As suggested in #68 (comment):

We should have the annotations @AndroidFindBy and @iOSFindBy support for native apps also. Currently it supports only for the web view.

I would also suggest from my point of view to make AppiumDriver as interface instead of keeping it as abstract.

@TikhomirovSergey
Copy link
Contributor

Hi!
They are designed generally for native apps. Please provide the detailed report of the problem that you've found. Stacktraces, locators, code samples etc. What locators do you use? What java_client version/server version? Below examples that work against native app:

@FindBy(css = "someBrowserCss") //this locator is used when here is browser (desktop or mobile) 
@iOSFindBy(uiAutomator = ".elements()[0]") //this locator is used when here is iOS native content 
@AndroidFindBy(className = "android.widget.TextView") //this locator is used when here is Android  
//native content 
public List<WebElement> androidOriOsTextViews; 


@AndroidFindBy(uiAutomator = "new UiSelector().resourceId(\"android:id/text1\")") 
public List<WebElement> androidUIAutomatorViews; 

@AndroidFindBy(uiAutomator = "new UiSelector().resourceId(\"android:id/text1\")") 
public List<MobileElement> mobileElementViews; //Also with Appium page object tools it is 
//possible to declare RemoteWebElement or any MobileElement subclass 

@FindBy(className = "android.widget.TextView") 
public List<MobileElement> mobiletextVieWs; 

@AndroidFindBy(uiAutomator = "new UiSelector().resourceId(\"android:id/text1\")") 
public List<RemoteWebElement> remoteElementViews; 


@AndroidFindBy(id = "android:id/text1") 
public WebElement textView; 

Full samples:
Android 1
Android 2
Android 3
iOS

About interface. Actually it exists. MobileDriver. There is new extended version that probably will be merged.

@Simon-Kaz
Copy link

@TikhomirovSergey I'm having issues with the following annotation:

@iOSFindBy(accessibility = "Tracker")
private MobileElement trackerButton;

When i use it, the following shows up in the the appium logs:

au.getElementsById('trackerButton')
au.getElementsByName('trackerButton')
au.getElementsByAccessibilityId('trackerButton')

It looks like the annotation is not passing the selector?

EDIT: I've just tried changing the "accessibility" to "name", and it's the same.

@TikhomirovSergey
Copy link
Contributor

Hi @Simon-Kaz
It is interesting. Is it browser test?

@Simon-Kaz
Copy link

Native app.

@TikhomirovSergey
Copy link
Contributor

Ok. I will try to repaet this today.
What java_client version you use? It will be nice if you provide capabilities that you use.

@Simon-Kaz
Copy link

Sure, I'm getting the data that I have right now... Will edit this post in a minute.

Java client 2.2.0. I'm running it on a highly customized spring+cucumber jvm framework but I reproduced it on regular cucumber jvm as well. I'll try and reproduce it without cucumber as well.

    capabilities.setCapability("platformName", "iOS");
    capabilities.setCapability("platformVersion", "8.1.2");
    capabilities.setCapability("deviceName", "iPhone 6");
    capabilities.setCapability("udid","random_digits");
    capabilities.setCapability("bundleId","bundle.id");
    capabilities.setCapability("autoAcceptAlerts","true");

    driver = new IOSDriver(new URL("http://0.0.0.0:4723/wd/hub"), capabilities);

@TikhomirovSergey
Copy link
Contributor

...and... I've forgotten to ask. Does this find the wrong element or throw the NoSuchElementException?

@Simon-Kaz
Copy link

No such element exception, as there's no element with that name/id/label.

@Simon-Kaz
Copy link

OK it works outside of my project, guess I'll have to do some digging and find out why the annotation is not working :(

@TikhomirovSergey
Copy link
Contributor

Can you define the path to your app like this or that. Does it help?
Do you define the path to your app via Appium desktop UI? What Appium server version you use?

@TikhomirovSergey
Copy link
Contributor

If I'm right then it is possible that your problem is related to appium/appium#4091. Given capabilities and capabilities that are defined in the server side via desktop UI are not merged. Then you have to define the path to app in Java code till it fixed.

@TikhomirovSergey
Copy link
Contributor

@Simon-Kaz @email2vimalraj

It seems I'm right. Please look below.

Here are settings:
1

The code:
1

The command

  ((IOSDriver) driver).getCapabilities()

returns

1

So Appium page object tools attempt to handle it the way like here is mobile or desktop browser. Because there is no FindBy and iOS/AndroidFindBy are for apps it tries to locate the element using Id or name that supposed to be equal to field name.

org.openqa.selenium.NoSuchElementException: Can't locate an element by this strategy: by id or name "iosButton"
For documentation on this error, please visit: http://seleniumhq.org/exceptions/no_such_element.html
Build info: version: '2.43.1', revision: '5163bceef1bc36d43f3dc0b83c88998168a363a0', time: '2014-09-10 09:43:55'
System info: host: 'Mac-Admin.local', ip: '192.168.42.129', os.name: 'Mac OS X', os.arch: 'x86_64', os.version: '10.9.5', java.version: '1.8.0_25'

It think the root cause has been described in referred issue appium/appium#4091. The workaround in my previous message.

@Simon-Kaz
Copy link

Sorry for late response - The reason I'm not specifying an app capability is because I have the app pre-installed with ideviceinstaller. I use bundleId and udid to run the tests.

Ideally I do not want the app installed using appium at all.

@Simon-Kaz
Copy link

I'd keep it open until I find a resolution, as it's still a problem for me. Once I find a solution, I'll update this ticket (for future reference if someone encounters the same issue) and close it then.

@TikhomirovSergey
Copy link
Contributor

Ok. I think the app should be calculated on the server-side and returned in capabilities (in your case). What do you think about this feature? If you find this cool and appium/appium#4091 is not relevant please open a new issue here: https://github.com/appium/appium/issues

Also I'll try to find another way to detect what is it right now - an app or browser.

@Simon-Kaz
Copy link

I just checked, and this is what's returned:

"platformVersion":"8.1.2",
"bundleId":"app's bundle id ",
"platformName":"iOS",
"udid":"udidNumber",
"deviceName":"iPhone 6",
"autoAcceptAlerts":true

Looks like it's not related to the issue you mentioned :( I'll try using app capability and see if that helps

EDIT: It's working with the app capability set... But how come? I shouldn't have to pass that capability if I use bundleId and udid right? Should I log a separate bug for that?

@TikhomirovSergey
Copy link
Contributor

It seems I know how to fix the app determination. Today I'll propose a pull-request.

@Simon-Kaz
Copy link

Perfect, thank you!

@TikhomirovSergey
Copy link
Contributor

Hi @Simon-Kaz
The fix is at reffered PR above. Please look at this. You could comment it and help me and @Jonahss

@Simon-Kaz
Copy link

I see it's been merged, that's great, thanks! Anything else that you need me to do? I can try and reproduce the issue with latest build of Appium.

@TikhomirovSergey
Copy link
Contributor

@Simon-Kaz you can review this. You can clone master, build it locally and try to reproduce... If you want :) The choice of By is smarter now and depends on the current context (when NATIVE_APP then it uses locators defined via AndroidFindBy/iOSFindBy and default Selenium FindBy otherwise)

@justintilson
Copy link

I'm getting a similar issue as @Simon-Kaz. I tried versions 2.2.0 and 3.0.0 with the same result.

Here is the constructor:

    public HomePhonePage(AppiumDriver driver) {
        super(driver);

        PageFactory.initElements(new AppiumFieldDecorator(driver,
                        IMPLICIT_WAIT,
                        TimeUnit.SECONDS),
                this
        );
    }

and a sample property from one of my page objects:

@iOSFindBy(accessibility = "home_landing_my_favorites_count_label")
WebElement myFavoritesCountLabel;

and a screenshot from my debugger:

unknown-locator

Instead of using the supplied accessibility identifier to locate elements, PageFactory.initElements is attempting to use the property name as the identifier.

It's behaving as if the annotation doesn't exist and is defaulting to use the page object property name.

Am I missing something?

@tomb50
Copy link

tomb50 commented Jul 31, 2015

This issue looks to still persist even with the fixes introduced with v3.1.0 which has the above, I am running against Appium 1.4.8 (no GUI app).

@IOSFindBy(accessibility = "123)
public WebElement abc

Is still trying to find using the instance variable value and not "123".

Please let me know if any additional info is required.

@tomb50
Copy link

tomb50 commented Jul 31, 2015

Just to confirm, the CONTEXT is NATIVE_APP and Desired Capabilities are the same as previous posters, the App is specified.

@tomb50
Copy link

tomb50 commented Jul 31, 2015

Disregard my comments, I was an idiot and was passing the driver directly into PageFactory.initElements() rather than a new AppiumFieldDecorator.

@robintel
Copy link

@tomb50

Hello,

It is unclear to me how you fixed it. Can you give some more details?

Thanks,
Robin

@nttrazvan
Copy link

Hello @tomb50 ,

Could you please provide a more detailed solution to this, I'm facing the same issue.

Razvan

@vikramvi
Copy link

@robintel @nttrazvan can you please check appium/appium#9780 and add your comments as well.

It's always better to create new issue than commenting on closed one.

@ppzzss
Copy link

ppzzss commented May 3, 2018

Below annotations work well in Appium 1.7.2

@iOSXCUITFindBy (xpath = "xxxx")
@AndroidFindBy (id = "bbbb")
public WebElement usernameTextField;

@ppzzss
Copy link

ppzzss commented May 3, 2018

with Java_client 5.0.4

@amrsa1
Copy link

amrsa1 commented Mar 27, 2019

Any one knows how to define an xpath that contains specific id and text using @AndroidFindBy

this is the element :
driver.findElement(By.xpath("//android.widget.TextView[contains(@resource-id,'com.sec.android.app.music:id/tab_text') and @text='TRACKS']"))

i tried to add it in that way :

@AndroidFindBy(xpath = ""//android.widget.TextView[contains(@resource-id,'com.sec.android.app.music:id/tab_text') and @text='TRACKS']"")
private WebElement TrackList;

but didnt work and shows me this message :

org.openqa.selenium.NoSuchElementException: Can't locate an element by this strategy: By.chained({By.xpath: "//android.widget.TextView[contains(@resource-id ='com.sec.android.app.music:id/tab_text') and @text='TRACKS']"})

@adityabhargav
Copy link

@TikhomirovSergey I'm having issues with the following annotation:

@iOSFindBy(accessibility = "Tracker")
private MobileElement trackerButton;

When i use it, the following shows up in the the appium logs:

au.getElementsById('trackerButton')
au.getElementsByName('trackerButton')
au.getElementsByAccessibilityId('trackerButton')

It looks like the annotation is not passing the selector?

EDIT: I've just tried changing the "accessibility" to "name", and it's the same.


Answer :-

@iOSFindBy(accessibility = "Tracker")
private MobileElement trackerButton;

trackerButton - is similar to "driver.findElement(By.Id("Tracker"))"

need to give like

trackerButton.Click();

Note:- trackerButton is not alone a mobile element , it carries property of "driver.findElement(By.Id("Tracker"))".

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 a pull request may close this issue.