简体   繁体   中英

Series of Multiple Actions in webdriver

I am just trying to enter a text in capital letters using set of keyboard actions. Here code using interface 'Action':

WebElement element = driver.findElement(By.id("email")); 
Actions builder = new Actions(driver); 
Action act = builder.moveToElement(element)
                    .keyDown(element,Keys.SHIFT)
                    .sendKeys("vishal")
                    .keyUp(Keys.SHIFT)
                    .build();
act.perform();

Above is working fine.

But if we do not use interface, it is not working why ??? Though this is executing fine but not performing the task. I think both should work.

WebElement element = driver.findElement(By.id("email")); 
Actions builder = new Actions(driver);
builder.moveToElement(element)
       .keyDown(element,Keys.SHIFT)
       .sendKeys("vishal")
       .keyUp(Keys.SHIFT)
       .build();
builder.perform();

In your second example, it's because you're calling build() then perform()

If you look at the Actions class implementations of those two methods:

  /**
   * Generates a composite action containing all actions so far, ready to be performed (and
   * resets the internal builder state, so subsequent calls to build() will contain fresh
   * sequences).
   *
   * @return the composite action
   */
  public Action build() {
    CompositeAction toReturn = action;
    resetCompositeAction();
    return toReturn;
  }

  /**
   * A convenience method for performing the actions without calling build() first.
   */
  public void perform() {
    build().perform();
  }

When you call build() it actually resets the internal state of the builder!

After that when you call perform() it rebuilds an empty object reference which has no behavior defined.

To correct the problem, I suggest replacing your call to build() with a call to perform() as shown below.

 WebElement element = driver.findElement(By.id("email")); 
 Actions builder = new Actions(driver);
 builder.moveToElement(element).keyDown(element, Keys.SHIFT).sendKeys("vishal").keyUp(Keys.SHIFT).perform();

I would expect that to do what you want, based on the implementation.

My investigation was done against selenium v 2.53.0

Because Actions#build() method resets a state of itself before returning the action,
see the implementation here: http://grepcode.com/file/repo1.maven.org/maven2/org.seleniumhq.selenium/selenium-api/2.18.0/org/openqa/selenium/interactions/Actions.java#Actions.build%28%29

338
339  public Action More ...build() {
340    CompositeAction toReturn = action;
341    resetCompositeAction();
342    return toReturn;
343  }

Pay attention to resetCompositeAction(); call - it resets the builder.

If you perform this:

 builder............
        ........ ().build();
builder.perform();

Then build() returns the action and resets a state of builder object.
Then if you call builder.perform() , it's do nothing.

builder.moveToElement(element)
       .keyDown(element,Keys.SHIFT)
       .sendKeys("vishal")
       .keyUp(Keys.SHIFT)
       .build().perform();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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