Selenium 3. Nawigacja pomiędzy stronami

Interesuje Cię ten kurs?

Dołącz do listy mailingowej, a poinformuję Cię o otwarciu zapisów.

W tej lekcji pokażę Ci w jaki sposób nawigować się pomiędzy stronami w Selenium.

Nawigacja pomiędzy stronami to akcje takie jak na przykład przejście na daną stronę albo cofnięcie się na poprzednią. Na tej lekcji dowiesz się jak mówić do Selenium, żebyśmy mogli za jego pomocą wykonać następujące akcje:

  • przejść na podaną stronę,
  • odświeżyć stronę,
  • przejść na poprzednią stronę z historii przeglądarki,
  • przejść na następną stronę z historii przeglądarki.

Chcesz się bardziej wgryźć w metody nawigacyjne? Link do dokumentacji Selenium, odpowiadający tym zagadnieniom znajdziesz tutaj: WebDriver.Navigation.

Kod

package DriverMethods;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.Dimension;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;


public class NavigationAndClosing {

    WebDriver driver;

    @BeforeEach
    public void driverSetup(){
        System.setProperty("webdriver.chrome.driver", "src/main/resources/chromedriver.exe");
        driver = new ChromeDriver();
        driver.manage().window().setSize(new Dimension(1280, 720));
    }
    @AfterEach
    public void driverQuit(){
        driver.close();
        driver.quit();
    }

    @Test
    public void getMethod(){
        driver.get("http://google.pl");
    }

    @Test
    public void navigate(){
        driver.navigate().to("https://google.pl");
        driver.navigate().to("https://www.amazon.com");
        driver.navigate().back();
        driver.navigate().forward();
        driver.navigate().refresh();
    }

}

Wsparcie merytoryczne

Nie masz aktywnego członkostwa. Wykup dostęp albo Zaloguj się, by móc zadawać pytania.

  1. Hej,
    w pierwszych dwoch lekcjach
    Przygotowanie środowiska programistycznego (DARMOWA LEKCJA)
    Inicjalizacja drivera i demo Selenium (DARMOWA LEKCJA)
    pracujesz na projekcie 'Start' w lokalizacji d:\dev\IntelliJ\start
    Natomiast w lekcji trzeciej rozumiem ze pracujemy juz na innym projekcie 'SeleniumTrainingBasics' d:\dev\IntelliJ\SeleniumTrainingBasics

    Pytanie czy ustawienia pierwszego i kolejnego projektu się różnią?'

    Odpowiedz
  2. Co do komentarza Piotra - też się chwilę musiałam nad tym zastanowić. Przydałaby się też możliwość ściągnięcia pliku danej klasy, żeby w razie czego sobie porównać/przekopiować jeśli coś nie działa 🙂

    Odpowiedz
  3. Nie potrafię stworzyć tak, żeby było jak na filmie.
    Na samej górze jest package a nie class i zabardzo nie umiem tego rozkminić, tak samo z nazwami projektów.
    No i pytanko odnośnie:
    Jak zaimportować  Dimension
    Również nie rozumiem zabardzo jak dojść do sytuacji java/DriverMethods/NavigattionAndClosing?
    Proszę o wyjaśnienie

    Odpowiedz
  4. Cześć,
    poniższy test mi nie działa. Jak go naprawić?

    package DriverMethods;
    
    import org.junit.jupiter.api.Test;
    import org.openqa.selenium.Dimension;
    import org.openqa.selenium.WebDriver;
    import org.openqa.selenium.chrome.ChromeDriver;
    
    public class NavigationAndClosing {
        @Test
        public void getMethod(){
            System.setProperty("webdriver.chrome.driver", "src/main/resources/chromedriver.exe");
            WebDriver driver = new ChromeDriver();
            driver.manage().window().setSize(new Dimension(width: 1280, height: 720 ));
    
    
            driver.get("http://google.pl");
    
            driver.quit();
    
    
        }
    }
    

    Error:(13, 80) java: ';' expected
    Error:(13, 61) java: ')' expected
    Error:(13, 77) java: not a statement

    Edit:
    Działa. Wpisałem słowa "width" i "height" ręcznie. Wystarczyło wpisać liczbę. Podpowiedź (dymek), która pojawiła się na górze była dla mnie myląca.

    Odpowiedz
  5. Hej. Nie działa mi ten test niestety. Pojawia mi się poniższy błąd. Nie mogę sobie z nim poradzić. Poprawiałam kod już kilka razy ale ciągle jest to samo. Na samym końcu dorzuciłam jeszcze kod.
    java.lang.NullPointerException
    at FirstTestSelenium.getMetod(FirstTestSelenium.java:24)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:567)
    at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:134)
    at org.testng.internal.TestInvoker.invokeMethod(TestInvoker.java:597)
    at org.testng.internal.TestInvoker.invokeTestMethod(TestInvoker.java:173)
    at org.testng.internal.MethodRunner.runInSequence(MethodRunner.java:46)
    at org.testng.internal.TestInvoker$MethodInvocationAgent.invoke(TestInvoker.java:816)
    at org.testng.internal.TestInvoker.invokeTestMethods(TestInvoker.java:146)
    at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:146)
    at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:128)
    at java.base/java.util.ArrayList.forEach(ArrayList.java:1507)
    at org.testng.TestRunner.privateRun(TestRunner.java:766)
    at org.testng.TestRunner.run(TestRunner.java:587)
    at org.testng.SuiteRunner.runTest(SuiteRunner.java:384)
    at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:378)
    at org.testng.SuiteRunner.privateRun(SuiteRunner.java:337)
    at org.testng.SuiteRunner.run(SuiteRunner.java:286)
    at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:53)
    at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:96)
    at org.testng.TestNG.runSuitesSequentially(TestNG.java:1187)
    at org.testng.TestNG.runSuitesLocally(TestNG.java:1109)
    at org.testng.TestNG.runSuites(TestNG.java:1039)
    at org.testng.TestNG.run(TestNG.java:1007)
    at com.intellij.rt.testng.IDEARemoteTestNG.run(IDEARemoteTestNG.java:66)
    at com.intellij.rt.testng.RemoteTestNGStarter.main(RemoteTestNGStarter.java:110)

    public class FirstTestSelenium {
    WebDriver driver ;

    @BeforeEach
    public void driveSetup (){
    System.setProperty("webdriver.chrome.driver","src/main/resources/chromedriver.exe");
    driver = new ChromeDriver();
    driver.manage().window().setSize(new Dimension(1295, 730));
    }

    @AfterEach
    public void driveQuit (){
    driver.quit();
    }
    @Test
    public void getMetod (){
    driver.get("https://google.com/");
    }
    @Test
    public void navigate (){
    }
    }

    Odpowiedz
  6. Z tego co kojarzę jeszcze różnica pomiędzy navigate() i get() jest taka, że przy get() tracimy historię gdyż nie jest to przechodzenie między stronami "zwykłego użytkownika" zatem też cookiesów nie będzie zapisywać. No i chyba navigate() jest trochę szybszy chociaż w testach to drugorzędna kwestia 😀

    Odpowiedz
      • Kiedyś tego szukałem bo mnie to zastanawiało i między innymi na stackoverflow się natknąłem na wpis:
        https://stackoverflow.com/questions/33865618/difference-between-webdriver-get-and-webdriver-navigate-to-in-the-case-of-ur/33868976#33868976
        Z tego co wyczytałem jeszcze tutaj https://www.seleniumeasy.com/selenium-tutorials/difference-between-webdriver-get-and-navigate
        To get czeka na załadowanie strony no i nie ma opcji w nim na .forward .backward ale skoro nie wynika to z kodu bezpośrednio to w sumie ciężko powiedzieć skąd to. Może przez to, że navigate wywołuje u siebie get to nie sprawdza już czy request w nim się w pełni zakończył zatem nie czeka na pełne załadowanie strony? Ogólnie raczej będę stosować navigate().to() dla tych dodatkowych opcji na poziomie składni ale ciekawe to!

        Odpowiedz
  7. Cześć Elu,
    W kodzie podajesz:

        @AfterEach
        public void driverQuit(){
            driver.close();
            driver.quit();
        }
    

    Mój kod:

    import org.junit.jupiter.api.Test;
    import org.openqa.selenium.WebDriver;
    import org.openqa.selenium.firefox.FirefoxDriver;
    import org.openqa.selenium.By;
    
    public class FirstTest {
        @Test
        public void demoTest() {
            System.setProperty("webdriver.gecko.driver", "src/main/resources/geckodriver.exe");
            WebDriver driver = new FirefoxDriver ();
            driver.navigate().to("https://google.pl");
            // akceptacja warunków google
            driver.findElement(By.id("L2AGLb")).click();
            driver.navigate().to("https://www.amazon.com");
            driver.navigate().back();
            driver.navigate().forward();
            driver.close();
            driver.quit();
        }
    }
    

    Gdy wykonuję kod zawierający close i quit to otrzymuję negatywny wynik testu.
    Gdy wykonuję kod zawierający close lub quit to wynik jest poprawny.
    Wykonanie close daje efekt:
    ###!!! [Child][RunMessage] Error: Channel closing: too late to send/recv, messages will be lost
    ###!!! [Child][MessageChannel::SendAndWait] Error: Channel error: cannot send/recv
    A następnie próba wykonania quit zwraca błędy:
    "org.openqa.selenium.NoSuchSessionException: Tried to run command without establishing a connection
    Build info: version: '3.141.59', revision: 'e82be7d358', time: '2018-11-14T08:17:03' (...)"

    A zatem jakie warunki należy spełnić aby wykonanie close i quit (jedno po drugim) było możliwe?
    Czy to może być kwestia konfiguracji stacji roboczej?

    Pozdrawiam serdecznie

    Odpowiedz
  8. Cześć! 🙂
    Męczę się z pewną rzeczą, przekopałam już trochę stack overflow i w sumie podane tam rozwiązania nie pomogły.
    Robiłam kurs 'Java dla testerów', takiego błędu jak mam teraz nie miałam, więc nie wykluczam że to coś z konfiguracją. Ostatnio musiałam zmieniać wersję drivera bo nie obsługiwał najnowszej wersji chrome.
    Natomiast błąd jaki mi się pojawia, przede wszystkim ma wpływ kiedy chcę coś odpalić w debugu. Testy przechodzą kiedy klikam run (dostaję info passed), ale mimo wszystko widzę następujący błąd:

    [SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
    SLF4J: Defaulting to no-operation (NOP) logger implementation
    SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
    Starting ChromeDriver 99.0.4844.51 (d537ec02474b5afe23684e7963d538896c63ac77-refs/branch-heads/4844@{#875}) on port 52634
    Only local connections are allowed.
    Please see https://chromedriver.chromium.org/security-considerations for suggestions on keeping ChromeDriver safe.
    ChromeDriver was started successfully.
    mar 13, 2022 1:32:09 PM org.openqa.selenium.remote.ProtocolHandshake createSession
    INFO: Detected dialect: W3C
    mar 13, 2022 1:32:09 PM org.openqa.selenium.devtools.CdpVersionFinder findNearestMatch
    WARNING: Unable to find an exact match for CDP version 99, so returning the closest version found: 97
    mar 13, 2022 1:32:09 PM org.openqa.selenium.devtools.CdpVersionFinder findNearestMatch
    INFO: Found CDP implementation for version 99 of 97

    Process finished with exit code 0]
    to powyżej pojawia się kiedy klikam, natomiast gdy klikam 'debug' przenosi mnie do 'Slf4JloggerFactory.java i podkreśla linijkę: ' throw new NoClassDefFoundError("NOPLoggerFactory not supported");

    W POMie mam nastepujące dependies:

    org.slf4j
    slf4j-api
    1.7.30

    Inne wersje niż 1.7.30 podkreśla na czerwono.
    Nie za bardzo mam pomysł co może być problemem.
    To mój kod:

    package DriverMethods;

    import org.junit.jupiter.api.AfterEach;
    import org.junit.jupiter.api.BeforeEach;
    import org.junit.jupiter.api.Test;
    import org.openqa.selenium.Dimension;
    import org.openqa.selenium.WebDriver;
    import org.openqa.selenium.chrome.ChromeDriver;

    public class NavigationAndClosing {

    WebDriver driver;

    @BeforeEach
    public void driverSetup(){
    System.setProperty("webdriver.chrome.driver", "src/main/resources/chromedriver.exe");
    driver = new ChromeDriver();
    driver.manage().window().setSize(new Dimension(1280, 720));
    }
    @AfterEach
    public void driverQuit(){
    driver.close();
    driver.quit();
    }

    @Test
    public void getMethod(){
    driver.get("http://google.pl");
    }

    @Test
    public void navigate(){
    driver.navigate().to("https://google.pl");
    driver.navigate().to("https://www.amazon.com");
    driver.navigate().back();
    driver.navigate().forward();
    driver.navigate().refresh();
    driver.getCurrentUrl();
    }

    Odpowiedz
  9. Hej,
    Mam pytanie o metodę driverQuit. W kodzie wielu osób widziałem, że w definicji takiej metody jest zabezpieczenie przed NullPointerException .

        public void driverQuit() {
            if (driver != null) {
                driver.quit();
            }
        }
    

    Taki zapis był użyty zwłaszcza przy zastosowaniu bardziej zawansowanych technik jak POM, testy parallel itp.
    W Twoim kodzie na tym etapie nie widzę takiego zabezpieczenia. Co sądzisz o stosowaniu takiego rozwiązania?
    Czy jest ono potrzebne, czy raczej zbędne?

    Odpowiedz
  10. i jeszcze małe pytanie.
    W linii 39 kodu zaprezentowanego w tekście powyżej masz
    driver.getCurrentUrl();
    Ten kod pobiera aktualny URL, ale nic z nim nie robi? Nie ma tam przypisania do zmiennej ani wyświetlenia w konsoli.
    Czy getCurrentUrl() jest tam w jakimś celu? Ta metoda robi coś jeszcze poza zwróceniem stringa z adresem?

    Odpowiedz