!!

Welcome to Selenium Webdriver Forum

As a web user you can read and search through forum content. Once you have registered and signed you can post topics, post replies, set up watch lists, modify forum settings, and use private messaging.

Author Topic: FindBy with dynamic using possible?  (Read 3525 times)

confusa

  • Web User
FindBy with dynamic using possible?
« on: April 09, 2012, 01:58:09 PM »
Trying to migrate from Selenium where I had a method like so in a
 PageObject:
         public void clickContent(String something) {
                 StringBuilder sb = new StringBuilder();
                 sb.append("//a[contains(@href, '/");
                 sb.append(something);
                 sb.append("')]");
                 String link = sb.toString();
                 clickAndWait(link);
         }
 
That worked like a charm but I am struggling with how to do this in
 WebDriver with a PageFactory created PageObject. I am thinking it
 needs to be something like so but I don't know how to get "something"
 in the annotation:
 
        @FindBy(how = How.XPATH, using = "//a[contains(@href, '/
 something')]")
         private WebElement contentLink;
 
Is what I am trying to do here possible or is there a better way?
 Basically I am trying to construct the xpath for the element with a
 variable.

Simon Stewart

  • Web User
Re: FindBy with dynamic using possible?
« Reply #1 on: April 09, 2012, 01:58:26 PM »
Annotations are static. You can, however, pretty easily write a custom
 ElementLocator that can build the By dynamically.
 Simon
 

- Show quoted text -

confusa

  • Web User
Re: FindBy with dynamic using possible?
« Reply #2 on: April 09, 2012, 01:58:37 PM »
Ahh, that sort of makes sense. Should I implement the
 ElementLocatorFactory
 interface and create my custom locator that way? A little confused on
 that approach as I would need a prefix, variable, and suffix to create
 the xpath.
 Thanks!
 
On Nov 18, 9:09 am, Simon Stewart <simon.m.stew...@gmail.com> wrote:
 

- Show quoted text -

Selenium Webdriver

Re: FindBy with dynamic using possible?
« Reply #2 on: April 09, 2012, 01:58:37 PM »

Simon Stewart

  • Web User
Re: FindBy with dynamic using possible?
« Reply #3 on: April 09, 2012, 01:58:49 PM »
Yup. That's what you need to do. An example would be:
 public class MyLocator implements ElementLocator {
  private final WebDriver driver;
  private final By by;
  private final boolean shouldCache;
  private WebElement cachedElement;
 
 public MyLocator(WebDriver driver, Field field) {
    this.driver = driver;
    Annotations annotations = new Annotations(field)
    shouldCache = annotations.isLookupCached();
 
   MyFindBy findBy = field.getAnnotation(MyFindBy.class);
    if (findBy != null) {
      by = deriveFrom(findBy);
    } else {
      by = annotations.buildBy();
    }
  }
 
 protected By deriveFrom(MyFindBy annotation) {
    // your magic here
  }
 
 public WebElement findElement() {
    if (cachedElement != null && shouldCache) {
      return cachedElement;
    }
 
   WebElement element = driver.findElement(by);
 
   if (shouldCache) {
      cachedElement = element;
    }
 
   return element;
  }
 

}
 

That's the hardest bit. The rest is up to you :)
 Simon
 

- Show quoted text -

confusa

  • Web User
Re: FindBy with dynamic using possible?
« Reply #4 on: April 09, 2012, 01:59:02 PM »
Sorry, still struggling a bit here. The example you gave above is
 giving me a "bound mismatch error":
 Bound mismatch: The generic method getAnnotation(Class<T>) of type
 AnnotatedElement is not applicable for the arguments
 (Class<ConstructedFindBy>). The inferred type ConstructedFindBy is not
 a valid substitute for the bounded parameter <T extends Annotation>
 ConstructedElementLocator.java  line 25
 
I am naming mine ConstructedFindBy by the way. Do I also need to
 create the ConstructedFindBy class?
 
Thanks for your help!
 
On Nov 19, 7:31 am, Simon Stewart <simon.m.stew...@gmail.com> wrote:
 

- Show quoted text -

Simon Stewart

  • Web User
Re: FindBy with dynamic using possible?
« Reply #5 on: April 09, 2012, 01:59:18 PM »
Presumably, yes.
 Simon
 

- Show quoted text -

confusa

  • Web User
Re: FindBy with dynamic using possible?
« Reply #6 on: April 09, 2012, 01:59:32 PM »
Think I have this now, I needed to create the ConstructedFindBy as an
 @interface similiar to the FindBy. Don't have it fully working yet,
 but at least the compiler stopped complaining!
 Thanks!
 
On Nov 24, 4:00 am, Simon Stewart <simon.m.stew...@gmail.com> wrote:
 

- Show quoted text -

Yanan

  • Web User
Re: FindBy with dynamic using possible?
« Reply #7 on: April 09, 2012, 01:59:48 PM »
Hi confusa,
 I'm having the same problem as you did and still struggling. Could you
 please share some samples?
 
Thank you in advance for the help!
 Yanan
 
On Nov 24 2010, 7:11 pm, confusa <materiaconf...@gmail.com> wrote:
 

- Show quoted text -

confusa

  • Web User
Re: FindBy with dynamic using possible?
« Reply #8 on: April 09, 2012, 02:00:09 PM »
Haven't had time to go back to this so it is not fully working. What I
 came up with so far, which may be wrong:
 @Retention(RetentionPolicy.RUNTIME)
 @Target(ElementType.FIELD)
 public @interface ConstructedFindBy {
     How how() default How.ID;
     String using();
 

}
 

Now the class:
 public class ConstructedElementLocator implements ElementLocator {
         private final WebDriver driver;
         private final By by;
         private final boolean shouldCache;
         private WebElement cachedElement;
 
        public ConstructedElementLocator(WebDriver driver, Field field) {
                 this.driver = driver;
                 Annotations annotations = new Annotations(field);
                 shouldCache = annotations.isLookupCached();
 
                ConstructedFindBy findBy =
 field.getAnnotation(ConstructedFindBy.class);
                 if (findBy != null) {
                         by = deriveFrom(findBy);
                 } else {
                         by = annotations.buildBy();
                 }
         }
 
        protected By deriveFrom(ConstructedFindBy annotation) {
                 // Need stuff here
         }
 
        public WebElement findElement() {
                 if (cachedElement != null && shouldCache) {
                         return cachedElement;
                 }
 
                WebElement element = driver.findElement(by);
 
                if (shouldCache) {
                         cachedElement = element;
                 }
 
                return element;
         }
 

}
 

Anyone else want to take a crack at it?
 On Jan 19, 6:16 pm, Yanan <baoj...@gmail.com> wrote:
 

- Show quoted text -

 

Related Topics

  Subject / Started by Replies Last post
8 Replies
1638 Views
Last post March 28, 2012, 09:48:31 PM
by confusa
4 Replies
1043 Views
Last post April 04, 2012, 08:19:38 PM
by Simon Stewart
4 Replies
1332 Views
Last post April 10, 2012, 01:59:50 PM
by Simon Stewart
3 Replies
1755 Views
Last post April 10, 2012, 07:53:28 PM
by Daniel Wagner-Hall
3 Replies
1064 Views
Last post April 10, 2012, 08:54:40 PM
by Daniel Wagner-Hall
2 Replies
1176 Views
Last post May 03, 2012, 11:02:06 PM
by Shaba K
3 Replies
1128 Views
Last post June 25, 2012, 02:15:20 PM
by Selenium Webdriver Admin