Skip to content

Commit

Permalink
introduce backwards compatible abstraction for @findby PageFactory ca…
Browse files Browse the repository at this point in the history
…pability

Signed-off-by: Simon Stewart <simon.m.stewart@gmail.com>
  • Loading branch information
paul-hammant authored and shs96c committed Jul 10, 2017
1 parent be77273 commit 0b30188
Show file tree
Hide file tree
Showing 9 changed files with 288 additions and 155 deletions.
149 changes: 149 additions & 0 deletions java/client/src/org/openqa/selenium/support/AbstractFindByBuilder.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.

package org.openqa.selenium.support;

import org.openqa.selenium.By;

import java.util.HashSet;
import java.util.Set;

public abstract class AbstractFindByBuilder {

public abstract By buildIt(Object annotation);

protected By buildByFromFindBy(FindBy findBy) {
assertValidFindBy(findBy);

By ans = buildByFromShortFindBy(findBy);
if (ans == null) {
ans = buildByFromLongFindBy(findBy);
}

return ans;
}

protected By buildByFromShortFindBy(FindBy findBy) {
if (!"".equals(findBy.className()))
return By.className(findBy.className());

if (!"".equals(findBy.css()))
return By.cssSelector(findBy.css());

if (!"".equals(findBy.id()))
return By.id(findBy.id());

if (!"".equals(findBy.linkText()))
return By.linkText(findBy.linkText());

if (!"".equals(findBy.name()))
return By.name(findBy.name());

if (!"".equals(findBy.partialLinkText()))
return By.partialLinkText(findBy.partialLinkText());

if (!"".equals(findBy.tagName()))
return By.tagName(findBy.tagName());

if (!"".equals(findBy.xpath()))
return By.xpath(findBy.xpath());

// Fall through
return null;
}

protected By buildByFromLongFindBy(FindBy findBy) {
How how = findBy.how();
String using = findBy.using();

switch (how) {
case CLASS_NAME:
return By.className(using);

case CSS:
return By.cssSelector(using);

case ID:
case UNSET:
return By.id(using);

case ID_OR_NAME:
return new ByIdOrName(using);

case LINK_TEXT:
return By.linkText(using);

case NAME:
return By.name(using);

case PARTIAL_LINK_TEXT:
return By.partialLinkText(using);

case TAG_NAME:
return By.tagName(using);

case XPATH:
return By.xpath(using);

default:
// Note that this shouldn't happen (eg, the above matches all
// possible values for the How enum)
throw new IllegalArgumentException("Cannot determine how to locate element ");
}
}

protected void assertValidFindBys(FindBys findBys) {
for (FindBy findBy : findBys.value()) {
assertValidFindBy(findBy);
}
}

protected void assertValidFindBy(FindBy findBy) {
if (findBy.how() != null) {
if (findBy.using() == null) {
throw new IllegalArgumentException(
"If you set the 'how' property, you must also set 'using'");
}
}

Set<String> finders = new HashSet<>();
if (!"".equals(findBy.using())) finders.add("how: " + findBy.using());
if (!"".equals(findBy.className())) finders.add("class name:" + findBy.className());
if (!"".equals(findBy.css())) finders.add("css:" + findBy.css());
if (!"".equals(findBy.id())) finders.add("id: " + findBy.id());
if (!"".equals(findBy.linkText())) finders.add("link text: " + findBy.linkText());
if (!"".equals(findBy.name())) finders.add("name: " + findBy.name());
if (!"".equals(findBy.partialLinkText()))
finders.add("partial link text: " + findBy.partialLinkText());
if (!"".equals(findBy.tagName())) finders.add("tag name: " + findBy.tagName());
if (!"".equals(findBy.xpath())) finders.add("xpath: " + findBy.xpath());

// A zero count is okay: it means to look by name or id.
if (finders.size() > 1) {
throw new IllegalArgumentException(
String.format("You must specify at most one location strategy. Number found: %d (%s)",
finders.size(), finders.toString()));
}
}

protected void assertValidFindAll(FindAll findBys) {
for (FindBy findBy : findBys.value()) {
assertValidFindBy(findBy);
}
}

}
2 changes: 2 additions & 0 deletions java/client/src/org/openqa/selenium/support/BUCK
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,15 @@ java_library(name = 'support',

java_library(name = 'page-factory',
srcs = [
'AbstractFindByBuilder.java',
'ByIdOrName.java',
'CacheLookup.java',
'FindAll.java',
'FindBy.java',
'FindBys.java',
'How.java',
'PageFactory.java',
'PageFactoryFinder.java',
] + glob(['pagefactory/*.java', 'pagefactory/internal/*.java',]),
deps = [
'//java/client/src/org/openqa/selenium:selenium',
Expand Down
22 changes: 22 additions & 0 deletions java/client/src/org/openqa/selenium/support/FindAll.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@

package org.openqa.selenium.support;

import org.openqa.selenium.By;
import org.openqa.selenium.support.pagefactory.ByAll;
import org.openqa.selenium.support.pagefactory.ByChained;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
Expand All @@ -38,6 +42,24 @@
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD, ElementType.TYPE})
@PageFactoryFinder(FindAll.FindByBuilder.class)
public @interface FindAll {
FindBy[] value();

public static class FindByBuilder extends AbstractFindByBuilder {
public By buildIt(Object annotation) {
FindAll findBys = (FindAll) annotation;
assertValidFindAll(findBys);

FindBy[] findByArray = findBys.value();
By[] byArray = new By[findByArray.length];
for (int i = 0; i < findByArray.length; i++) {
byArray[i] = buildByFromFindBy(findByArray[i]);
}

return new ByAll(byArray);
}

}

}
21 changes: 21 additions & 0 deletions java/client/src/org/openqa/selenium/support/FindBy.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@

package org.openqa.selenium.support;

import org.openqa.selenium.By;
import org.openqa.selenium.support.pagefactory.ByChained;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
Expand Down Expand Up @@ -51,6 +54,7 @@
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD, ElementType.TYPE})
@PageFactoryFinder(FindBy.FindByBuilder.class)
public @interface FindBy {
How how() default How.UNSET;

Expand All @@ -71,4 +75,21 @@
String partialLinkText() default "";

String xpath() default "";

public static class FindByBuilder extends AbstractFindByBuilder {
public By buildIt(Object annotation) {
FindBy findBy = (FindBy) annotation;
assertValidFindBy(findBy);

By ans = buildByFromShortFindBy(findBy);
if (ans == null) {
ans = buildByFromLongFindBy(findBy);
}

return ans;

}

}

}
20 changes: 20 additions & 0 deletions java/client/src/org/openqa/selenium/support/FindBys.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@

package org.openqa.selenium.support;

import org.openqa.selenium.By;
import org.openqa.selenium.support.pagefactory.ByChained;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
Expand All @@ -37,6 +40,23 @@
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD, ElementType.TYPE})
@PageFactoryFinder(FindBys.FindByBuilder.class)
public @interface FindBys {
FindBy[] value();

public static class FindByBuilder extends AbstractFindByBuilder {
public By buildIt(Object annotation) {
FindBys findBys = (FindBys) annotation;
assertValidFindBys(findBys);

FindBy[] findByArray = findBys.value();
By[] byArray = new By[findByArray.length];
for (int i = 0; i < findByArray.length; i++) {
byArray[i] = buildByFromFindBy(findByArray[i]);
}

return new ByChained(byArray);
}

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package org.openqa.selenium.support;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

@Retention(RetentionPolicy.RUNTIME)
public @interface PageFactoryFinder {
Class<? extends AbstractFindByBuilder> value();
}
Loading

0 comments on commit 0b30188

Please sign in to comment.