Selenium w C# wywala błąd.

0

Mam taki mały problem z Selenium w C#. Pokazuje się błąd "NoSuchElementException was unhandled" gdy test dochodzi do wpisywania hasła.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using OpenQA.Selenium;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium.Support.UI;

namespace Selenium
{
    class Program
    {
        static void Main(string[] args)
        {
            IWebDriver driver = new FirefoxDriver();
            driver.Navigate().GoToUrl("http://www.t-mobilebankowe.pl");

            IWebElement zaloguj = driver.FindElement(By.LinkText("Zaloguj"));
            zaloguj.Click();

            IWebElement login = driver.FindElement(By.Id("LoginID"));
            login.SendKeys("login");

            IWebElement button = driver.FindElement(By.LinkText("Zaloguj"));
            button.Click();

            IWebElement password = driver.FindElement(By.Id("login_password"));
           //NoSuchElementException was unhandled
            password.SendKeys("haslo");
        }
    }
}

teraz fragment html

<input class="x-form-text x-form-field aliorie8fix alior-textfield L x-form-invalid" autocomplete="off" maxlength="100" id="login_password" name="Credentials" type="password">

Oczywiście w kodzie podawałem poprawny login i hasło.
Co robię źle?

1

Jeśli login jest krótki to nie łąduje się fragment z podaniem hasła, ale prosi o wężyka i pewnie to jest problem (jak podaje login "sd" to prosi o wężyka).

0

Nie,
W moim przypadku loginem jest numer 8 cyfrowy, po naciśnięciu przycisku pojawia mi się pole do wpisywania hasła.

0

A czasem pojawia się tak. ;) Mi tam program działa jak jest standardowe wpisywanie hasła. :)

0

Nie u mnie pojawia się standardowe pole tekstowe do wpisywania hasła. na razie chcę spróbować Selenium na moim koncie.

2

Inny możliwy powód to czas ładowania fragmentu strony. Nie wiem jak w Selenium, ale WatiN, szukał określonego elementu przez określony czas (licząc na odświeżenie fragmentu strony, przez skrypt). Teraz pytanie, jak Selenium radzi sobie z dynamicznymi elementami strony? Bo jeśli tylko czeka, aż strona będzie załadowana i nie bierze pod uwagę możliwości, że skrypt podmienia fragment strony, to może być to problem.
Z tego co doczytałem na szybkiego to button.Click(); powinno byś blokujące dopóki strona się nie załaduje, a u ciebie ostatnie kliknięcie nie powoduje przeładowanie strony (skrypt modyfikuje fragment), przy czym w dokumentacji nie widziałem SendKeys oczekiwało na pojawienie się potrzebnego elementu, wiec możliwe, że mam rację.

Jeśli mam rację, możesz spróbować napisać pętlę, która będzie czekać aż element się pojawi (sprawdzając równocześnie jakiś timeout).

2

Czyli jeśli @MarekR22 ma racje to takie coś powinno pomóc:

driver.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(10));

An implicit wait is to tell WebDriver to poll the DOM for a certain amount of time when trying to find an element or elements if they are not immediately available. The default setting is 0. Once set, the implicit wait is set for the life of the WebDriver object instance

lub tak:

IWebDriver driver = new FirefoxDriver();
driver.Url = "http://www.t-mobilebankowe.pl";
WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
IWebElement password = wait.Until<IWebElement>((d) =>
    {
        return d.FindElement(By.Id("login_password"));
    });

Źródło: http://docs.seleniumhq.org/docs/04_webdriver_advanced.jsp

0

@MarekR22 miał rację, teraz już działa wszystko w porządku. Dzięki.

0

Odradzam robienie czegoś takiego za pomocą sleepa na okresloną liczbę sekund. Musiałem kiedyś poprawiać takie genialne metody "synchronizacji". Bo kiedyś komputer się przywiesi, internet zeświruje i strona się załaduje po 11 a nie po 10 sekundach i się wysypie taki test ;)
Takiego sleepa na określony czas trzeba niestety zapętlić i jako warunek pętli sprawdzać czy element na który czekamy się już pojawił.

0

Nie miałem okazji nic pisać w selenium. Ale czy w tym przypadku nie wystarczy po prostu ustawić nie wiem jedną minute albo i dwie. ;)

DibbyDum napisał(a):
WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
IWebElement password = wait.Until<IWebElement>((d) =>
    {
        return d.FindElement(By.Id("login_password"));
    });

Bo zgodnie z dokumentacją:

WebDriverWait by default calls the ExpectedCondition every 500 milliseconds until it returns successfully.

I tak nas to nie boli co najwyżej na błąd dłużej poczekamy?

1 użytkowników online, w tym zalogowanych: 0, gości: 1