Как я могу выйти из всех циклов после того, как я нахожу свой элемент (ссылку) в таблице - PullRequest
0 голосов
/ 07 мая 2018

Таблица проекта содержит список проектов. При нажатии на проект в столбце проекта (идентификатор, имя, личная информация и т. Д.) Открывается страница сведений о проекте. Автоматизация найти проект и нажать на него, но я получаю эту ошибку

OpenQA.Selenium.StaleElementReferenceException: ссылка на элемент из устарел; либо элемент больше не привязан к DOM, это не в текущем контексте кадра, или документ был обновилась

Я думаю, что после нажатия на проект, после перехода на страницу сведений о Proj, цикл не останавливается. как я могу сломаться; из всех петель после того, как я найду свой проект Я новичок в области автоматизации, мне нужна помощь

public static void SelectProject()
{
    IWebElement Table = Driver.Instance.FindElement(By.Id("projectsGrid"));
    ReadOnlyCollection<IWebElement> allRows = Table.FindElements(By.TagName("tr"));
    foreach (IWebElement row in allRows)
    {
        ReadOnlyCollection<IWebElement> cells = row.FindElements(By.TagName("td"));
        foreach (IWebElement cell in cells)
        {
            if (cell.Text.Contains("002032"))
            {
                cell.Click();
                break;
            }
        }
    }
}

Ответы [ 4 ]

0 голосов
/ 10 мая 2018

Вы можете избавиться от 99% логики в этой функции с хорошим локатором.

public void SelectProject()
{
    Driver.Instance.FindElement(By.XPath("[@id='projectsGrid']//td[.='002032']")).Click();
}

Приведенный выше метод сгенерирует исключение, если этот элемент не существует. Ваш текущий метод не будет ничего делать (генерировать исключение или щелкать элемент), если элемент не существует. Если вы хотите такое поведение, используйте код ниже.

public void SelectProject()
{
    IReadOnlyCollection<IWebElement> e = Driver.Instance.FindElements(By.XPath("[@id='projectsGrid']//td[.='002032']"));
    if (e.Any())
    {
        e.ElementAt(0).Click();
    }
}
0 голосов
/ 07 мая 2018

Я лично стараюсь избегать операторов break, поэтому я бы попытался использовать while или for со значением часового, но если вы хотите использовать foreach, вы должны включить bool, который решает, прерывать ли вы для каждого цикла. Как только вы найдете то, что вы хотите, затем установите Bool. Например:

public static void SelectProject()
{
    IWebElement Table = Driver.Instance.FindElement(By.Id("projectsGrid"));
    ReadOnlyCollection<IWebElement> allRows = 
        Table.FindElements(By.TagName("tr"));

    bool loop = true;

    foreach (IWebElement row in allRows)
    {
        ReadOnlyCollection<IWebElement> cells = 
            row.FindElements(By.TagName("td"));
        foreach (IWebElement cell in cells)
        {
            if (cell.Text.Contains("002032"))
        {
            cell.Click();
            loop = false;
        }
             if (!loop)
             break;
        }
        if (!loop)
                break;
        }
}
0 голосов
/ 08 мая 2018

Флаги не нужны, используйте return вместо break.

return;
0 голосов
/ 07 мая 2018

Вы можете использовать логический флаг с именем done. Первоначально оно ложно, и только get получает значение true перед тем, как выйти из внутреннего цикла. Если вы разорвете внутренний цикл, сразу после этого во внешнем цикле проверьте, что done == true. Если это так, это означает, что вы разорвали внутренний цикл, поэтому вам следует разорвать и внешний цикл.

public static void SelectProject()
{
    // Boolean flag for when we break from inner loop
    bool done = false;

    IWebElement Table = Driver.Instance.FindElement(By.Id("projectsGrid"));
    ReadOnlyCollection<IWebElement> allRows = Table.FindElements(By.TagName("tr"));
    foreach (IWebElement row in allRows)
    {
        ReadOnlyCollection<IWebElement> cells = row.FindElements(By.TagName("td"));
        foreach (IWebElement cell in cells)
        {
            if (cell.Text.Contains("002032"))
            {
                cell.Click();
                done = true;
                break;
            }
        }

        // Check if the inner loop 
        // broke, if so also break here
        if (done == true) {
            break;
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...