Определите, присутствует ли Angular перед вызовом FindElement - PullRequest
1 голос
/ 07 июня 2019

У меня есть следующие драйверы браузера:

public IWebDriver Browser { get; }
public NgWebDriver NgBrowser { get; }

Когда я пытаюсь найти элемент с помощью селектора XPath, если Angular отсутствует, он не будет работать, если я использую NgBrowser:

var byXpath = By.XPath(exp);
var link = NgBrowser.FindElement(byXpath);

Но если я попытаюсь найти его с помощью Browser и Angular присутствует, он не найдет его:

var byXpath = By.XPath(exp);
var link = Browser.FindElement(byXpath);

Должен ли я просто обернуть вызов NgBrowser в try...catch иповторная попытка с Browser, если он выдает?Или есть более простой, более прямой метод?Возможно, что-то со встроенным переключением при сбое?

.csproj:

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <TargetFramework>netcoreapp2.1</TargetFramework>
    <IsPackable>false</IsPackable>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.1.0" />
    <PackageReference Include="Newtonsoft.Json" Version="12.0.2" />
    <PackageReference Include="Protractor" Version="0.12.0" />
    <PackageReference Include="Selenium.Support" Version="3.141.0" />
    <PackageReference Include="Selenium.WebDriver" Version="3.141.0" />
    <PackageReference Include="Selenium.WebDriver.ChromeDriver" Version="2.46.0" />
    <PackageReference Include="specflow" Version="3.0.199" />
    <PackageReference Include="SpecFlow.Tools.MsBuild.Generation" Version="3.0.199" />
    <PackageReference Include="SpecFlow.MsTest" Version="3.0.199" />
    <PackageReference Include="MSTest.TestFramework" Version="2.0.0-build-20190430-01" />
    <PackageReference Include="MSTest.TestAdapter" Version="2.0.0-build-20190430-01" />
  </ItemGroup>

</Project>

Лучшее, что у меня есть сейчас, это:

[Given(@"I go to url (.*)")]
public void GoToUrl(string url)
{
    NgBrowser
        .Navigate()
        .GoToUrl(url, false);
}

Пока это решаетпроблема обнаружения Angular во время навигации по страницам, она не отвечает на вопрос этого поста;А именно, что простое обнаружение Angular отдельно от выполнения операции (особенно FindElement) представляется невозможным.

1 Ответ

2 голосов
/ 17 июня 2019

Когда Angular загружает, он добавляет свои собственные классы, например ng-untouched ng-pristine ng-valid к элементам.

Если вы напрямую сопоставляете значения ваших классов в XPath, это может быть причиной того, что вы не можете найти элементы, когда угловые

Что касается веб-драйвера, вы можете использовать этот веб-драйвер , который имеет встроенный метод ожидания загрузки Angular.

Если вы хотите обработатьСамостоятельно, вы можете написать класс, подобный этому:

import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.support.ui.ExpectedCondition;

public class AdditionalConditions {
    public static ExpectedCondition<Boolean> angularHasFinishedProcessing() {
        return new ExpectedCondition<Boolean>() {
            @Override
            public Boolean apply(WebDriver driver) {
                return Boolean.valueOf(((JavascriptExecutor) driver).executeScript("return (window.angular !== undefined) && (angular.element(document).injector() !== undefined) && (angular.element(document).injector().get('$http').pendingRequests.length === 0)").toString());
            }
        };
    }
}

Он проверит наличие углового в window объекте, чтобы увидеть, загружен ли угловой в вашем приложении.

Вы можете использовать это так:

WebDriverWait wait = new WebDriverWait(getDriver(), 15, 100);
wait.until(AdditionalConditions.angularHasFinishedProcessing()));

Надеюсь, это поможет.

...