Skip to content

@AndroidFindBy and @iOSFindBy for native app automation #184

Closed

Description

@email2vimalraj

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.

Activity

  1. TikhomirovSergey commented on Apr 15, 2015

    @TikhomirovSergey
    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.

  2. Simon-Kaz commented on Apr 23, 2015

    @Simon-Kaz

    @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.

  3. TikhomirovSergey commented on Apr 23, 2015

    @TikhomirovSergey
    Contributor

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

  4. Simon-Kaz commented on Apr 23, 2015

    @Simon-Kaz

    Native app.

  5. TikhomirovSergey commented on Apr 23, 2015

    @TikhomirovSergey
    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.

  6. Simon-Kaz commented on Apr 23, 2015

    @Simon-Kaz

    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);
    
  7. TikhomirovSergey commented on Apr 23, 2015

    @TikhomirovSergey
    Contributor

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

  8. Simon-Kaz commented on Apr 23, 2015

    @Simon-Kaz

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

  9. Simon-Kaz commented on Apr 23, 2015

    @Simon-Kaz

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

  10. TikhomirovSergey commented on Apr 23, 2015

    @TikhomirovSergey
    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?

  11. TikhomirovSergey commented on Apr 23, 2015

    @TikhomirovSergey
    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.

  12. TikhomirovSergey commented on Apr 23, 2015

    @TikhomirovSergey
    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.

  13. Simon-Kaz commented on Apr 24, 2015

    @Simon-Kaz

    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.

  14. Simon-Kaz commented on Apr 24, 2015

    @Simon-Kaz

    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.

  15. TikhomirovSergey commented on Apr 24, 2015

    @TikhomirovSergey
    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.

  16. 5 remaining items

  17. Simon-Kaz commented on Apr 28, 2015

    @Simon-Kaz

    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.

  18. TikhomirovSergey commented on Apr 28, 2015

    @TikhomirovSergey
    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)

  19. justintilson commented on Jun 30, 2015

    @justintilson

    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?

  20. added a commit that references this issue on Jul 6, 2015
  21. tomb50 commented on Jul 31, 2015

    @tomb50

    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.

  22. tomb50 commented on Jul 31, 2015

    @tomb50

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

  23. tomb50 commented on Jul 31, 2015

    @tomb50

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

  24. robintel commented on Nov 23, 2017

    @robintel

    @tomb50

    Hello,

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

    Thanks,
    Robin

  25. nttrazvan commented on Nov 24, 2017

    @nttrazvan

    Hello @tomb50 ,

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

    Razvan

  26. vikramvi commented on Dec 12, 2017

    @vikramvi

    @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.

  27. ppzzss commented on May 3, 2018

    @ppzzss

    Below annotations work well in Appium 1.7.2

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

  28. ppzzss commented on May 3, 2018

    @ppzzss

    with Java_client 5.0.4

  29. amrsa1 commented on Mar 27, 2019

    @amrsa1

    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']"})

  30. adityabhargav commented on Aug 14, 2019

    @adityabhargav

    @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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions