简体   繁体   English

如何装饰硒WebDriver类?

[英]how to decorate the selenium WebDriver class?

I want to add some functionality to the WebDriver class. 我想向WebDriver类添加一些功能。 I've tried to use the pattern decorator. 我试图使用模式装饰器。 I think it's the best in this situation for add functionalities to WebDriver class without change it. 我认为在这种情况下最好将功能添加到WebDriver类而不更改它。

This my code : 这是我的代码:

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 FirefoxDriverExtends.class

public class FirefoxDriverExtends extends DriverExtends {

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

}

My test case : 我的测试用例:

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;
   }
}

And this the error i get : 这是我得到的错误:

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

It's the first time i use the decorator pattern. 这是我第一次使用装饰器模式。 So what i've missed? 那我错过了什么? :) :)

i assume, the issue is with initialization of RemoteWebDriver. 我认为,问题在于RemoteWebDriver的初始化。 You cannot inject the firefox driver to RWD object rather specify the capabilities. 您无法将firefox驱动程序注入RWD对象,而不能指定功能。 Check this doc. 检查此文档。

Ok, i've found how to do this. 好的,我已经找到方法。 This is the solution. 这是解决方案。 In decorator pattern you must map all method of decorated object with the decorator object. 在装饰器模式中,必须将装饰对象的所有方法与装饰器对象进行映射。

First we can see that RemoteWebDriver.class is the super class of all webDriver objects. 首先,我们可以看到RemoteWebDriver.class是所有webDriver对象的超类。 So to decorate RemoteWebDriver we must create class that implement all of RemoteWebDriver's interfaces. 因此,要装饰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.

}

Next we need to implements this decorator with our browser implementation. 接下来,我们需要通过浏览器实现来实现此装饰器。 Let's go with firefox example. 让我们来看一个Firefox示例。 In this class we need to map all methods to the corresponding FirefoxDriver class 在此类中,我们需要将所有方法映射到相应的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.

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM