2012-03-01 75 views
0

我想知道WebDriver中WebElement的ID是如何在内部计算的。我需要它,因为我正在编写一个扩展,以便在需要一次执行多个JavaScript命令的情况下提高性能。如何计算WebDriver WebElement的内部ID?将多个元素传递给JavaScript Executor

示例代码在Java中以检索ID:

RemoteWebElement element = driver.findElement(
    By.cssSelector("div#header > img.logo") 
); 
String id = element.getId(); 
// id is something like: {390f457d-406b-458a-b4a6-dfebb24aae36} 

所以,我想不止一个WebElement传递到JavaScript的执行者,我可以通过发送所有的ID列表实现的呢? 我只需要知道这些id就可以在JavaScript中检索DOM元素。

我想解决方案是隐藏在webdriver.xpi实现中的某个地方。我使用Firefox WebDriver。

更新

好吧,让我重复我的问题。假设我想要做的事,在JavaScript中的WebElement我可以做这样的事情:

((JavascriptExecutor) driver).executeScript("jQuery(arguments[0]).doSomething()", myElement); 

但我怎么能传递多个WebElements(任意金额)的脚本?

+0

顺便说一句,我没有在我的java WebDriver实现中找到getID ... – 2012-03-01 14:19:52

+0

它在'RemoteWebElement'中定义:http://selenium.googlecode.com/svn/trunk/docs/api/java/org/ openqa/selenium/remote/RemoteWebElement.html#getId%28% – Alp 2012-03-01 14:23:58

+0

啊!看着'WebElement'我的坏:) – 2012-03-01 14:26:32

回答

1

我相信JavascriptExecutor.ExecuteScript()方法会将WebElements的集合作为参数。该项目的JavaScript execution tests中有单元测试,表明这是可能的。如果是这样的话,为什么以下方法不起作用?

List<WebElement> elements = driver.findElements(By.cssSelector("div#header > img.logo")); 
((JavascriptExecutor)driver).ExecuteScript("for (var i = 0; i < arguments[0].length; i++) { jQuery(arguments[0][i]).doSomething(); }", elements); 

以下示例在我使用的电流源(Java代码)为:

WebDriver driver = new FirefoxDriver(); 
driver.get("http://www.google.com"); 
List<WebElement> elements = driver.findElements(By.tagName("div")); 
String s = (String)((JavascriptExecutor)driver).executeScript("var s=''; for (var i = 0; i < arguments[0].length; i++) { s += arguments[0][i].tagName; } return s;", elements); 
driver.quit(); 
System.out.println(s); 

我收到 “DIVDIVDIVDIVDIVDIVDIVDIV ......” 打印到控制台窗口。

+0

感谢,这看起来很有希望,但这似乎产生一个错误(使用对象数组,如'testCanHandleAnArrayOfElementsAsAnObjectArray()')所示:'参数是一个非法类型:[Ljava.lang.Object;'在类'WebElementToJsonConverter'你可以看到没有一个WebElements数组的处理程序,也没有一个对象数组... – Alp 2012-03-01 16:54:58

+0

我已经简化了这个例子。对象数组中间步骤没有任何需要。在WebElementToJsonConverter中**有一个处理集合,其中列表是一个。请注意,转换器是递归的,所以它应该将列表中的所有元素转换为JSON表示形式。 – JimEvans 2012-03-01 17:56:22

+0

非常感谢,帮助了我。我完全错过了转换器是递归的。我仍在努力解决细节问题,但它似乎现在起作用了! – Alp 2012-03-01 23:00:32

0

顺便说一下,findElements()方法重新运行元素列表。所以,你的代码会更喜欢:

List<WebElement> elements = driver.findElements(By.cssSelector("div#header > img.logo"); 

,然后如果你想让它传递给一些别的方法,你为什么不使用for周期?:

for (WebElement elem : elements){ 
    doSomethingWithElement(elem); 
} 

以上会经过的所有元素,并使用他们一个接一个地循环。

另一种方法是将WebElement包裹到您的自定义类 - 但这样,你必须实现所有抽象方法:

public class MyWebElement implements WebElement{ 
private int id; // ID of the element which you can define later on 
private WebElement theElement // wrap around this beauty 
// .. 
} 
+0

对不起,我的代码中的错误,我纠正它。这只是一个显示FireFox WebDriver的内部ID格式的例子。我仍然需要一种方法来访问相应的元素,只有通过在JavaScript中了解这个ID。 – Alp 2012-03-01 13:34:24

+0

啊!我完全误解了你想达到的目标。要发布另一个答案:) – 2012-03-01 13:49:38

0

好了,如果我现在可以正确undrstand它,你有更多的您的DOM中的图像。所以,你的HTML看起来像这样:

<div id="header"> 
<img class="logo" id="firstID" src="foo.jpg" /> 

假设这个ID是不是很好,而不是猜测的,所以你根本不能做的最简单的方法:

WebElement img = driver.findElement(By.id("firstID"); 

或将其传递给方法通过一些简单的搜索。 (像检查元素,然后做类似的事情):

(JavaScriptExecutor).executeScript(doSomethingWithId("firstID")); 

好的。这样就可以做到这一点:

WebElement element = driver.findElement(By.cssSelector("div#header > img.logo")); 
String id = element.getAttribute("id"); 

以上应该会返回为firstID作为字符串值。我从来没有在我的测试中试过,但我希望它能工作

+0

这仍然不是我想要的。我不知道如何正确表达自己,以便看到我想要做的事情。这是一项普遍的任务,不限于图像。假设我有一个'findElements()'命令,它返回一个'WebElement'对象列表。我想通过调用列表中的'getId()'来放置所有的内部id(我不是说html id属性)。这个列表被发送给一个JavaScript执行者,然后需要通过知道这些ID来检索相应的元素。 – Alp 2012-03-01 14:09:48

+0

但WebElement内部ID与现实世界ID无关。 WebElement是DOM中一个HTML元素的Java表示。 JavaScript应该用真正的HTML做一些事情。为什么Javascript应该只知道ID?我很迷茫... – 2012-03-01 14:13:57

+0

感谢您的帮助。我更新了我的问题,也许现在更精确。 – Alp 2012-03-01 14:21:39