В настоящее время я пытаюсь внедрить e2e тестирование веб-сайта, который в значительной степени опирается на AngularJs с использованием Selenium/Fluentlenium.
Раньше я использовал этот подход без проблем, но кажется, что phantomJS просто не может работать с Angular.
Если я "просматриваю источник страницы" в Chrome, все, что я вижу, это привязки (например, {{object.item}}), если я, однако, "проверяю элемент", я получаю то, что получаю от ожидаемого контента.
Скажем, наш html выглядит так (и загружается с помощью $ http, и предположим, что $ scope.loading является ложным после заполнения $ scope.objects):
<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.
EDIT: Мне жаль, что мой вопрос был недостаточно ясным, я должен был включить следующий фрагмент кода 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, первый флажок должен быть проверен, а второй - нет.
Похоже, ваш селен работает правильно в соответствии с вашим кодом - есть только один элемент с классом = "item1"
То, что вы, вероятно, хотите, это что-то вроде
List<WebElement> item1s = driver.findElements(By.tagName("td"));
Если это не приведет к результатам, которые вы хотите, пожалуйста, объясните более четко, что является правильным ожидаемым результатом.
item1
. Вы можете использовать некоторый xpath, чтобы найти все соответствующие элементы, или получить все тегиtd
и отфильтровать их перед обработкой.