Autor: Michał Dobrzycki
Czym jest Selenium WebDriver?
To narzędzie do automatyzacji pracy z przeglądarką.
Narzędzie dojrzałe, aktualnie mamy wersję 4.1 (a na rynku jest od 2004 roku)
Pozwala pisać testy w większości języków programowania.
Składa się z paru komponentów
Czym nie jest Selenium WebDriver?
Kompletnym narzędziem do testowania.
Rozwiązaniem wszystkich naszych bolączek.
Czy Selenium WebDriver umie sterować bezpośrednio przeglądarką?
Selenium do pracy potrzebuje driverów -> aplikacji tworzonych przez producentów przeglądarki.
Większość producentów dostarcza drivery do swoich przeglądarek.
Paczki do zainstalowania nugetem
Będziemy jeszcze potrzebować drivera w wersji kompatybilnej z przeglądarką na naszym komputerze.
Sklonujcie projekt i robimy zadanie 1
Metody IWebDriver
IWebDriver driver = new ChromeDriver;
driver.Url="https://www.bing.com";
driver.Quit();
Szukanie elementów po:
IWebElement loginButton = driver.FindElement(By.Id("login"));
Css Selector, szukanie oparte na klasach css (stylowanie)
XPath, szukanie oparte na strukturze HTML
Metody IWebElement:
Dobre rady:
Zadanie 2 do zrobienia
.FindElements()
Możemy zwracać listę (tablicę na sterydach) pasujących WebElementów
IList <IWebElement> elements = driver.FindElements(By.CssSelector("p"));
foreach (IWebElement element in elements) {
Console.WriteLine(element.Text);
}
Konsola i walidacja selektorów w konsoli przeglądarki
CSS Selector:
$$(".inventory_item_name")
XPath:
$x("//a")
Obydwie funkcje mają overload z $0 (szukamy w aktualnie zaznaczonym elemencie)
$$(".inventory_item_name", $0)
Property IWebElement:
Zadanie 4 do zrobienia
Specjalny element, czyli SelectElement
Wymaga instalacji paczki nuget: Selenium.Support, pozwala na
IWebElement sortDropdownElement = driver.FindElement(By.Id("..."));
var selectDropdown = new SelectElement(sortDropdownElement);
selectDropdown.SelectByValue("...")
Zadanie 4 i 5 do zrobienia
Implicit Wait
Nie zalecane, ponieważ czeka na KAŻDY element określoną ilość czasu
driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(10);
Explicit Wait
Nie mieszamy ich z Implicit Wait, bo czasy zaczynają nam się sumować
var foo = new WebDriverWait(driver, TimeSpan.FromSeconds(3))
.Until(drv => drv.FindElement(By.Name("q")));
ExpectedConditions (wymaga Selenium 3.141 - porzucono w Selenium 4)
new WebDriverWait(driver, TimeSpan.FromSeconds(3))
.Until(ExpectedConditions.ElementToBeClickable(By.XPath("//a/h3")));
Fluent Wait
Pozwala określić jak często bedziemy próbowali znaleźć ponownie element
Może być dobre do zredukowania ilości zapytań, jeżeli wiemy że element pojawi się późno.
Przykład czekania aż element zniknie:
WebDriverWait wait = new WebDriverWait(driver, timeout: TimeSpan.FromSeconds(10))
{
PollingInterval = TimeSpan.FromSeconds(1),
};
wait.Until(driver =>
!driver.FindElement(By.Id("ajaxBusy")).Displayed);
Przykład Actions (using OpenQA.Selenium.Interactions;)
IWebElement expandingDiv = driver.FindElement(By.CssSelector(".expand"));
Actions action = new Actions(driver);
action.MoveToElement(expandingDiv);
action.Perform();
Upload plików
Dodajemy folder files do którego wrzucamy plik kotek.jpg, ustawiając mu property Copy always
string pathToFile = @".\files\kotek.jpg";
fileInput.SendKeys(Path.GetFullPath(pathToFile));
Pobieranie plików
Musimy ustawić opcje ChromeDrivera (pamiętajcie o nie zamykaniu przeglądarki zanim nie skończymy pobierać pliku)
ChromeOptions options = new ChromeOptions();
options.AddUserProfilePreference("download.default_directory", @"C:\downloads\");
options.AddUserProfilePreference("disable-popup-blocking", "true");
options.AddUserProfilePreference("download.prompt_for_download", false);
driver = new ChromeDriver(options);
Założenia:
Przykład testu:
LoginPage loginPage = new LoginPage(driver);
loginPage.loginAs("user@firma.pl", "Password1");
Assert.assertEquals("User FullName", loginPage.getLoggedUsername());
Teraz zostało tylko napisać LoginPage, prywatne lokatory elementów i jej dwie publiczne metody
Linki warte przeczytania:
Piszemy w pliku .feature
When I search for '.NET BDD framework'
A w klasie która implementuje kroki
[When(@"I search for '(.*)'"]
public void WhenIPerformASimpleSearchOn(string searchTerm)
{
//kod testujący aplikację
}
Przykładowy Framework
Do obsługi plików JSON polecam:
Pozwala na serializację i deserializację plików JSON (json -> obiekt -> json)
Tworzymy .json z konfiguracją frameworka
{
"Browser": "Chrome",
"DownloadFolder": "TestResult",
"RunAsHeadless": false,
"ImplicitWaitTimeout": 10
}
Tworzymy klasę która będzie zamieniać jsona na obiekt
[JsonProperty("Browser", Required = Required.Always)]
[JsonConverter(typeof(StringEnumConverter))]
public readonly BrowserType CurrentBrowser;
Przed uruchomieniem odczytujemy plik, tworzymy obiekt i przekazujemy jako parametr do tworzenia Drivera
string settingsJson = File.ReadAllText(
Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "TestSettings.json"));
TestSettings settings = JsonConvert.DeserializeObject<TestSettings>(settingsJson);
Driver.Initialize(settings);
Uruchomcie docker desktop i wrzućcie komendy do cmd.exe / powershella
docker pull selenium/hub:4.1.2-20220208
docker pull selenium/node-chrome:4.1.2-20220208
docker pull selenium/node-edge:4.1.2-20220208
docker pull selenium/node-firefox:4.1.2-20220208
Repozytorium z projektem
Włączamy docker desktop
Odpalamy komendę z cmd.exe (tam gdzie jest plik docker-compose.yml)
docker-compose up
Odpalamy przeglądarkę na http://localhost:4444
Analizujemy kod projektu, uruchamiamy testy i podglądamy http://localhost:4444.
Darmowe źródła:
Źródła warte zainwestowania