如何装饰selenium WebDriver类?

时间:2014-04-09 13:45:05

标签: java selenium-webdriver

我想为WebDriver类添加一些功能。我试过使用模式装饰器。我认为在这种情况下,在不改变它的情况下向WebDriver类添加功能是最好的。

这是我的代码:

public abstract class DriverExtends extends RemoteWebDriver {

   protected Log logger = LogFactory.getLog(getClass());
   protected RemoteWebDriver rwd;
   protected final int SLEEP = 10;

   public DriverExtends(RemoteWebDriver driver) {
         rwd = driver;
   }

   /**
   * Determines whether an element is present on the page.
   * @param by The search item.
   * @param log if true, logs a message in the log in the absence of the element. False otherwise.
   * @return true if the element is present, false otherwise.
   */
   public boolean isElementPresent(By by, boolean log) {
         try{
                (new WebDriverWait(rwd, SLEEP)).until(ExpectedConditions.presenceOfElementLocated(by));
                return true;
         } catch(NoSuchElementException e) {
                if(log) {
                       logger.warn("L'élément est absent : "+ e.getMessage());
                }
                return false;
         }
   }

   /**
   * Allows click on a submenu hide default.
   * @param by The link to click. Example (By.linkText ("Search"));
   */
   public void loadMenu(By by) {
         rwd.findElement(By.id("bouton_menu")).click();
         ((JavascriptExecutor)rwd).executeScript("$(\".menu2\").show()");
         rwd.findElement(by).click();
   }
}

FirefoxDriverExtends.class

public class FirefoxDriverExtends extends DriverExtends {

       public FirefoxDriverExtends (FirefoxDriver driver) {
             super(driver);
       }

}

我的测试用例:

public class CreatePeople extends DefaultTestCaseWithParam<PersonLoaded> {

   @Override
   public boolean test(DriverExtends driver, PersonLoaded p) throws InterruptedException, TimeoutException {
         System.out.println("CreatePeople.test() - " + p);
         driver.loadMenu(By.linkText("Recherche"));
         (new WebDriverWait(driver, SLEEP)).until(ExpectedConditions.presenceOfElementLocated(By.id("idform:nom_input"))).sendKeys(p.getPrenom());
         driver.findElement(By.id("idform:datenaiss_input")).sendKeys(p.getDateNaiss());
         new Select(driver.findElement(By.id("idform:paysRR"))).selectByValue("Danemark");
         (new WebDriverWait(driver, SLEEP)).until(ExpectedConditions.elementToBeClickable(By.id("idform:villeRR"))).sendKeys("COPENHAGUE");
         driver.findElement(By.id("idform:rechercherRes")).click();
         (new WebDriverWait(driver, SLEEP)).until(ExpectedConditions.presenceOfElementLocated(By.id("idform:creerRes"))).click();
         new Select((new WebDriverWait(driver, SLEEP)).until(ExpectedConditions.presenceOfElementLocated(By.id("People:selecGestio")))).selectByVisibleText("SELENIUM-UN SELENIUM");
         driver.findElement(By.id("People:adresse")).sendKeys("01 rue du test");
         driver.findElement(By.id("People:telT")).sendKeys("0102030405");
         new Select(driver.findElement(By.id("People:posS"))).selectByVisibleText("someText");
         new Select((new WebDriverWait(driver, SLEEP)).until(ExpectedConditions.presenceOfElementLocated(By.id("People:categAD")))).selectByVisibleText("someText");
         new Select(driver.findElement(By.id("People:autoEmploi"))).selectByVisibleText("Armée de l'air");
         new Select((new WebDriverWait(driver, SLEEP)).until(ExpectedConditions.presenceOfElementLocated(By.id("People:categP")))).selectByVisibleText("someText");
         new Select(driver.findElement(By.id("People:precMili"))).selectByVisibleText("De carrière");
         new Select((new WebDriverWait(driver, SLEEP)).until(ExpectedConditions.presenceOfElementLocated(By.id("People:categH")))).selectByVisibleText("someText");
         driver.findElement(By.id("id=People:date_debut-service_input")).click();
         driver.findElement(By.linkText("1")).click();
         return true;
   }
}

这就是我得到的错误:

uild info: version: '2.41.0', revision: '3192d8a6c4449dc285928ba024779344f5423c58', time: '2014-03-27 11:29:39'
System info: host: 'UCFC4DD43D730B', ip: '36.138.1.237', os.name: 'Windows 7', os.arch: 'amd64', os.version: '6.1', java.version: '1.7.0_25'
Driver info: driver.version: RemoteWebDriver
org.openqa.selenium.remote.UnreachableBrowserException: Error communicating with the remote browser. It may have died.
Build info: version: '2.41.0', revision: '3192d8a6c4449dc285928ba024779344f5423c58', time: '2014-03-27 11:29:39'
System info: host: 'UCFC4DD43D730B', ip: '36.138.1.237', os.name: 'Windows 7', os.arch: 'amd64', os.version: '6.1', java.version: '1.7.0_25'
Driver info: driver.version: RemoteWebDriver
       at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:589)
-Start of the timer for "Test 4 - selenium.tests.testsuites.TestSuitePeople.testCreatePeople"
09/04/2014 15:10:00 (DbUnit.java:173)  [INFO ]: Désactivation des contraintes
       at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:610)
       at org.openqa.selenium.remote.RemoteWebDriver.getScreenshotAs(RemoteWebDriver.java:320)
       at selenium.utils.jUnit.SeleniumTestWatcher.failed(SeleniumTestWatcher.java:68)
       at org.junit.rules.TestWatchman$1.evaluate(TestWatchman.java:51)
       at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
       at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31)
       at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:76)
       at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
       at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
       at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
       at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
       at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
       at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
       at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
       at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31)
       at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
       at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
       at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
       at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
       at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
       at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
       at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
Caused by: java.lang.NullPointerException
       at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:568)
       ... 22 more

这是我第一次使用装饰器模式。那么我错过了什么? :)

2 个答案:

答案 0 :(得分:0)

我假设,问题在于RemoteWebDriver的初始化。您不能将firefox驱动程序注入RWD对象而是指定功能。查看this doc.

答案 1 :(得分:0)

好的,我已经找到了如何做到这一点。这是解决方案。在装饰器模式中,您必须使用装饰器对象映射装饰对象的所有方法。

首先我们可以看到RemoteWebDriver.class是所有webDriver对象的超类。因此,为了装饰RemoteWebDriver,我们必须创建实现所有RemoteWebDriver接口的类。

public abstract class DriverCustom implements WebDriver, JavascriptExecutor,
FindsById, FindsByClassName, FindsByLinkText, FindsByName,
FindsByCssSelector, FindsByTagName, FindsByXPath,
HasInputDevices, HasCapabilities, TakesScreenshot {

    //Our decorated object
protected RemoteWebDriver rwd;

public DriverCustom(RemoteWebDriver driver) {
    rwd = driver;
}

// custom methods to add to the decorator. Must be public.

}

接下来,我们需要使用我们的浏览器实现来实现这个装饰器。让我们来看看Firefox的例子吧。在这个类中,我们需要将所有方法映射到相应的FirefoxDriver类

public class FirefoxDriverCustom extends DriverCustom {

    // Add decorated object to decorator
public FirefoxDriverCustom(FirefoxDriver driver) {
    super(driver);
}

@Override
public void get(String url) {
    rwd.get(url);
}

@Override
public String getCurrentUrl() {
    return rwd.getCurrentUrl();
}

@Override
public String getTitle() {
    return rwd.getTitle();
}

@Override
public List<WebElement> findElements(By by) {
    return rwd.findElements(by);
}

@Override
public WebElement findElement(By by) {
    return rwd.findElement(by);
}

@Override
public String getPageSource() {
    return rwd.getPageSource();
}

@Override
public void close() {
    rwd.close();

}

@Override
public void quit() {
    rwd.close();

}

@Override
public Set<String> getWindowHandles() {
    return rwd.getWindowHandles();
}

@Override
public String getWindowHandle() {
    return rwd.getWindowHandle();
}

@Override
public TargetLocator switchTo() {
    return rwd.switchTo();
}

@Override
public Navigation navigate() {
    return rwd.navigate();
}

@Override
public Options manage() {
    return rwd.manage();
}

@Override
public Object executeScript(String script, Object... args) {
    return rwd.executeScript(script, args);
}

@Override
public Object executeAsyncScript(String script, Object... args) {
    return rwd.executeAsyncScript(script, args);
}

@Override
public WebElement findElementById(String using) {
    return rwd.findElementById(using);
}

@Override
public List<WebElement> findElementsById(String using) {
    return rwd.findElementsById(using);
}

@Override
public WebElement findElementByClassName(String using) {
    return rwd.findElementByClassName(using);
}

@Override
public List<WebElement> findElementsByClassName(String using) {
    return rwd.findElementsByClassName(using);
}

@Override
public WebElement findElementByLinkText(String using) {
    return rwd.findElementByLinkText(using);
}

@Override
public List<WebElement> findElementsByLinkText(String using) {
    return rwd.findElementsByLinkText(using);
}

@Override
public WebElement findElementByPartialLinkText(String using) {
    return rwd.findElementByPartialLinkText(using);
}

@Override
public List<WebElement> findElementsByPartialLinkText(String using) {
    return rwd.findElementsByPartialLinkText(using);
}

@Override
public WebElement findElementByName(String using) {
    return rwd.findElementByName(using);
}

@Override
public List<WebElement> findElementsByName(String using) {
    return findElementsByName(using);
}

@Override
public WebElement findElementByCssSelector(String using) {
    return rwd.findElementByCssSelector(using);
}

@Override
public List<WebElement> findElementsByCssSelector(String using) {
    return rwd.findElementsByCssSelector(using);
}

@Override
public WebElement findElementByTagName(String using) {
    return rwd.findElementByTagName(using);
}

@Override
public List<WebElement> findElementsByTagName(String using) {
    return rwd.findElementsByTagName(using);
}

@Override
public WebElement findElementByXPath(String using) {
    return rwd.findElementByXPath(using);
}

@Override
public List<WebElement> findElementsByXPath(String using) {
    return rwd.findElementsByXPath(using);
}

@Override
public Keyboard getKeyboard() {
    return rwd.getKeyboard();
}

@Override
public Mouse getMouse() {
    return rwd.getMouse();
}

@Override
public Capabilities getCapabilities() {
    return rwd.getCapabilities();
}

@Override
public <X> X getScreenshotAs(OutputType<X> target)
        throws WebDriverException {
    return rwd.getScreenshotAs(target);
}

// We can also add some specific firefox's methods to our decorator class.

}