【问题标题】:Retrieving Selenium <tr> WebElements after AngularJs populates table在 AngularJs 填充表格后检索 Selenium <tr> WebElements
【发布时间】:2016-03-22 19:44:08
【问题描述】:

我目前正在尝试使用 Selenium/Fluentlenium 对严重依赖 AngularJs 的网站实施 e2e 测试。

我之前使用过这种方法没有任何问题,但似乎 phantomJS 根本无法处理正在运行的 Angular。

如果我在 Chrome 中“查看页面源代码”,我看到的只是绑定(例如 {{ object.item }}),但是如果我“检查元素”,我会得到我期望的内容。

假设我们的 html 看起来像这样(并且由 $http 加载,并假设在 $scope.objects 填充后 $scope.loading 为 false):

<table ng-show="!loading" id="itemList">
<tbody>
    <tr ng-repeat="object in objects">
        <td class="item1">{{ object.item1 }}</td>
        <td class="item2">{{ object.item2 }}</td>
        <td class="item3">{{ object.item3 }}</td>
        <td class="itemSafe"><input type="checkbox" disabled="true" ng-checked="object.itemSafe == 1"></td>
    </tr>
</tbody>
</table>

到目前为止,这是我得到的:

private static final int TIMEOUT = 10;
private static final int PORT = 3333;
protected static final String URL = "http://localhost:" + PORT;

public static PhantomJSDriver driver = setupWebDriver();
public static WebDriverWait wait = new WebDriverWait(driver, TIMEOUT);
public static TestBrowser browser = testBrowser(driver);

    private static PhantomJSDriver setupWebDriver() {
        DesiredCapabilities caps = new DesiredCapabilities();
        caps.setJavascriptEnabled(true);

        LoggingPreferences logPrefs = new LoggingPreferences();
        logPrefs.enable(LogType.BROWSER, Level.ALL);
        caps.setCapability(CapabilityType.LOGGING_PREFS, logPrefs);

        String path = findDriverPath(); //Not relevant, just finds the binary
        caps.setCapability(PhantomJSDriverService.PHANTOMJS_EXECUTABLE_PATH_PROPERTY, path);
        return new PhantomJSDriver(caps);
    }

    @Before
    public static void setup() throws Throwable {
        driver.manage().window().setSize(new Dimension(1280, 720));
        driver.get(URL);
    }

    @Test
    public void testFindItem1(){
            browser.$("#items").click();  //opening site has link with id
            wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("itemList")));  //table element
            browser.$("#filter").text("item1Text");  //input element for filtering
            List<WebElement> item1s = driver.findElements(By.className("item1"));
            for(WebElement item1: item1s){
            System.out.println(item1.getText()); //outputs "{{ object.item1 }}"  once <-- MY PROBLEM
        }
    }

....这只会导致“{{ object.item1 }}”被打印一次,但在 Chrome 中可以完美运行。

编辑: 很抱歉我的问题不够清楚,我应该包含以下一段 javascript 代码:

$scope.objects = [{item1: "one", item2: "two", item3: "three", itemSafe: "1"}, {item1: "four", item2: "five", item3: "six", itemSafe: "0"}];
$scope.loading = false;

鉴于此,我预期的 html 是:

<tr>
<td class="item1">one</td>
<td class="item2">two<td>
<td class="item3">three</td>
<td class="itemSafe"><input type="checkbox" disabled="true" ng-checked="object.itemSafe == 1"></td>
</tr>
<tr>
<td class="item1">four</td>
<td class="item2">five<td>
<td class="item3">six</td>
<td class="itemSafe"><input type="checkbox" disabled="true" ng-checked="object.itemSafe == 1"></td> 
</tr>

请注意,鉴于 JSON 数组,应选中第一个复选框,但不应选中第二个复选框。

【问题讨论】:

  • 根据您粘贴的 html,这是正确的行为 - 只有一个元素具有 item1 类。您可以使用一些 xpath 来查找所有相关元素,或者获取所有 td 标签并在处理之前对其进行过滤。

标签: java angularjs selenium phantomjs fluentlenium


【解决方案1】:

看起来你的 selenium 按照你的代码正常工作 - 只有一个元素 class= "item1"

你可能想要的是类似

List<WebElement> item1s = driver.findElements(By.tagName("td"));

如果这不能产生您想要的结果,请更清楚地解释正确的预期结果是什么。

【讨论】:

    猜你喜欢
    • 2020-02-12
    • 1970-01-01
    • 1970-01-01
    • 2018-11-04
    • 1970-01-01
    • 2020-10-28
    • 2023-04-04
    • 2019-01-30
    • 1970-01-01
    相关资源
    最近更新 更多