Skip to content
This repository has been archived by the owner on Nov 29, 2018. It is now read-only.

Enhance PageFactory to use dynamic locators #3567

Closed
lukeis opened this issue Mar 3, 2016 · 9 comments
Closed

Enhance PageFactory to use dynamic locators #3567

lukeis opened this issue Mar 3, 2016 · 9 comments

Comments

@lukeis
Copy link
Member

lukeis commented Mar 3, 2016

Originally reported on Google Code with ID 3567

We have a webdriver setup that keeps all element lookup strings 
(xpaths, ids, etc) in one place (a database that gets dumped to a java class).

It would be nice to have this work with PageObject @FindBy() annotation. Maybe like
this:

   @FindBy(loader=MyClass, index="someKey")

where MyClass implements PageFactoryFinder, and the key is passed to 
say the MyClass() constructor, with MyClass.getLocatorType() and
MyClass.getLocatorKey() returning the equivalent of e.g.  By.id and 
the id string respectively.

This would allow the merging of PageObjects with centralized tag tracking.
It would also allow us to spit out different tags depending on what 
language the user has selected on the site, e.g. where link text has 
changed from English to Spanish.

Reported by ross@cgl.ucsf.edu on 2012-03-14 22:04:50

@lukeis
Copy link
Member Author

lukeis commented Mar 3, 2016

Reported by luke.semerau on 2012-03-14 23:18:45

  • Labels added: Type-Enhancement, Lang-Java, Component-WebDriver, PageFactory
  • Labels removed: Type-Defect

@lukeis
Copy link
Member Author

lukeis commented Mar 3, 2016

This is currently implementable by implementing your own FindBy annotation and ElementLocatorFactory;
I'd be happy to accept a patch which implemented these.

Reported by dawagner on 2012-03-17 23:22:27

@lukeis
Copy link
Member Author

lukeis commented Mar 3, 2016

I have verified this code in my own application, and added two tests based on that implementation,
but haven't been able to get the ./go cmd line to run the tests, so although they compile,
they haven't been run.

---------------- How to use ----------------------------------------

Here's an example of use in a Page Object:

  @FindBy(locatorGeneratorFactory = "com.get.rich.GeneratedQadbConstants",
          locatorKey="UNSIGNED_HOMEPAGE_SIGN_UP_BUTTON_ELEMENT")
  private WebElement signUpLink;

First implement LocatorGeneratorFactory, such that a String (locatorKey)
will return a LocatorGenerator. Here is how I did it: each LocatorGenerator
is an object contained in the factory class, e.g.

    public static final ISectionElement
        UNSIGNED_HOMEPAGE_SIGN_UP_BUTTON_ELEMENT = new SectionElement(1,
           "Sign Up", SectionElementType.BUTTON, ElementLocatorType.XPATH,
           "//a[@href='/signUp']", 1, "language.signUp");

Note that the name of the object corresponds to the @FindBy locatorKey
above. (Also, the classes and interface are non-selenium.) I used
reflection to look up the fields in the factory:

    public LocatorGenerator getLocatorGenerator(String key) {
        try {
            Field field = this.getClass().getField(key);
            return (LocatorGenerator) field.get(this);
        } catch (NoSuchFieldException nsf) {
            throw new RuntimeException("Unknown field: "+key);
        } catch (IllegalAccessException iae) {
            throw new RuntimeException("Illegal access, field: "+key);
        }
    }

Then I made my existing SectionElement class implement LocatorGenerator,
generating the By on the fly. Now if I want, I can expand this class
further to allow the By generation to toggle, e.g. depending on which
language all the link text is in as the user changes the site's language
selection. But even without this benefit, I have saved writing several
lines of code for each WebElement I want to use.

Root dir: selenium-read-only/java/client/src/org/openqa/selenium/ 

Reported by ross@cgl.ucsf.edu on 2012-04-11 20:45:41

@lukeis
Copy link
Member Author

lukeis commented Mar 3, 2016

Here is a cmd to run the relevant tests:

$ ./go //java/client/test/org/openqa/selenium/support:SmallTests:run

In debugging the test, I found that for the reflection-based MyLocatorGeneratorFactory
in the test code, the LocatorGenerator fields need to be public. 

The attachment has 4 plain files, plus the diffs on the existing ones.

Reported by ross@cgl.ucsf.edu on 2012-04-12 19:32:24


- _Attachment: [sel_3567_patch2](https://storage.googleapis.com/google-code-attachments/selenium/issue-3567/comment-4/sel_3567_patch2)_

@lukeis
Copy link
Member Author

lukeis commented Mar 3, 2016

Hi!

Please confirm you have signed the CLA [1].

Also maybe you could update your patch for last code 
and apply it as pull request via github [2] ?

[1] http://goo.gl/qC50R
[2] https://github.com/SeleniumHQ/selenium

Reported by a.u.savchuk on 2013-08-02 23:07:03

@lukeis
Copy link
Member Author

lukeis commented Mar 3, 2016

Reported by a.u.savchuk on 2013-08-16 14:39:00

@lukeis
Copy link
Member Author

lukeis commented Mar 3, 2016

Reassigning to Daniel as I'm not quite sure why this patch exists.

As he points out i comment 2, the PageFactory was designed to be extended by just implementing
ElementLocatorFactory and passing that in. That, in turn, would make use of a custom
annotation. To make it easy to implement your own custom annotations and factories,
yet retain the behaviour of the default @FindBy, there's the Annotations class that
you can use.

Marking as NeedsClarification because I'm not sure what Daniel was asking, and I'm
fairly convinced that the infrastructure this requires already exists.

Reported by simon.m.stewart on 2014-01-29 14:22:35

  • Status changed: NeedsClarification

@lukeis
Copy link
Member Author

lukeis commented Mar 3, 2016

Closed as per #7

Reported by dawagner on 2014-02-08 06:48:07

  • Status changed: WontFix

@lukeis
Copy link
Member Author

lukeis commented Mar 3, 2016

Reported by luke.semerau on 2015-09-17 18:15:03

  • Labels added: Restrict-AddIssueComment-Commit

@lukeis lukeis closed this as completed Mar 3, 2016
@SeleniumHQ SeleniumHQ locked and limited conversation to collaborators Mar 4, 2016
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

1 participant