Twój pierwszy Screenshot w Selenium WebDriver

Na początku zacznijmy od stworzenia nowego projektu o nazwie BasicScreenshotTests wraz z własnym venv, w którym będziemy eksperymentowali ze zrzutami ekranu. Nasz nowy projekt umieśćmy w katalogu Projects, tak aby struktura folderów wyglądała w następujący sposób:

C:
+-- Projects
|   +-- BasicScreenshotTests
|      +-- venv
|         +-- ...
|      +-- ...
|   ...
...
TIP: Generalnie aby stworzyć nowy projekt wystarczy kliknąć w górnym menu PyCharma File -> New Project… i w katalogu Projects utworzyć projekt z sugerowaną nazwą i domyślnym ustawieniem Project Interpreter.
W razie problemów tworzenie projektu za pomocą IDE PyCharm omówiliśmy w lekcji Tworzymy projekt, natomiast tworzenie środowiska wirtualnego – w sekcji Python Virtual Environment.

Następnie przygotujmy sobie:

  1. Klasę testową o nazwie BasicScreenshotTests w pliku basic_screenshot_tests.py.
  2. Następnie dodamy metody setUp oraz tearDown, w których odpowiednio przygotujemy sobie moduł webdriver. Będzie on bazował na naszym chromedriver.exe (dla przypomnienia – Drugi kod – korzystamy z modułu WebDriver).
  3. Doinstalujmy brakujący pakiet selenium (dla przypomnienia – Pierwszy kod – pojawia się Selenium).
  4. Napiszmy prosty test, który będzie odwiedzał stronę https://antoogle.testoneo.com/ oraz sparawdzał jej tytuł.

Całość mogłaby wyglądać w następujący sposób:

import unittest
from selenium import webdriver


class BasicScreenshotTests(unittest.TestCase):

   def setUp(self):
      self.base_url = 'https://antoogle.testoneo.com/'
      self.driver = webdriver.Chrome(executable_path=r"C:\TestFiles\chromedriver.exe")

   def tearDown(self):
      self.driver.quit()

   def test_open_antoogle(self):
      self.driver.get(self.base_url)
      self.assertEqual('The Antoogle Search Page', self.driver.title, f'Expected title differ from actual for page url: {self.base_url}')

Teraz poznamy metodę odpowiedzialną za tworzenie screenshotów driver.get_screenshot(). Użyjemy ją w naszym kodzie zaraz przed linią z asercją w taki sposób:

self.driver.get_screenshot_as_file("screenshot.png")

Czyż nie wygląda banalnie? Możemy także podejrzeć jej dokumentację.
Mamy trzy sposoby:

  1. Poprzez naciśnięcie skrótu szybkiego podglądu dokumentacji Ctrl + Q. Przypominamy, że niestety twórcy PyCharama zmienili sposób działania tego podglądu (niestety na gorsze) i często trzeba uciekać się do innych sposobów aby podglądnąć pełną dokumentację
  2. Przejście bezpośrednio do biblioteki selenium gdzie istnieje implementacja tej metody poprzez przytrzymanie klawisza Ctrl i naciśnięcie lewym przyciskiem myszy na naszą metodę
  3. Udając się do oficjalnej dokumentacji dostępnej pod tym adresem

Z dwóch ostatnich sposobów możemy odnaleźć przykład użycia naszej metody – najszybszym wydaje się przejście do jej implementacji (sposób 2) – w wyniku, którego możemy zobaczyć oryginalną dokumentację do kodu tej metody:

def get_screenshot_as_file(self, filename):
   """
   Saves a screenshot of the current window to a PNG image file. Returns
      False if there is any IOError, else returns True. Use full paths in
      your filename.

   :Args:
    - filename: The full path you wish to save your screenshot to. This
      should end with a `.png` extension.

   :Usage:
       driver.get_screenshot_as_file('/Screenshots/foo.png')
   """

Widzimy, że metoda ta przyjmuje jeden argument, którym jest ścieżka z nazwą pliku, pod którym zostanie zapisany nasz zrzut ekranu. Jeśli umieścimy tam tylko nazwę pliku, to obraz zostanie zapisany w katalogu z plikiem z naszym testem. Przykładowo, w naszym wypadku ścieżka C:\Pojects\BasicScreenshotTests\screenshot.png będzie równoznaczna z screenshot.png – w obu przypadkach obraz zostanie zapisany w pliku o nazwie screenshot.png w katalogu C:\Pojects\BasicScreenshotTests\, gdyż tam znajdują się nasze skrypty z testami.

Tak wygląda nasz udoskonalony test z zastosowaniem:
self.driver.get_screenshot_as_file("screenshot.png"):

import unittest
from selenium import webdriver


class BasicScreenshotTests(unittest.TestCase):

   def setUp(self):
      self.base_url = 'https://antoogle.testoneo.com/'
      self.driver = webdriver.Chrome(executable_path=r"C:\TestFiles\chromedriver.exe")

   def tearDown(self):
      self.driver.quit()

   def test_open_antoogle(self):
      self.driver.get(self.base_url)
      self.driver.get_screenshot_as_file("screenshot.png")
      self.assertEqual('The Antoogle Search Page', self.driver.title, f'Expected title differ from actual for page url: {self.base_url}')

Co się stanie jeśli go uruchomimy? Poza tym, że przeglądarka otworzy się jedynie na ułamek sekundy, to w naszym katalogu projektowym pojawi się plik o nazwie screenshot.png, na którym ujrzymy testowaną stronę internetową. W PyCharmie powinieneś zobaczyć ten plik w lewym panelu Project zaraz pod plikiem z naszą klasą.
Otwieramy otrzymany plik screenshot.png bezpośrednio w PyCharmie co oznacza, że bez problemu możemy w naszym IDE podglądać pliki graficzne. Nawet znajdziemy u góry zakładki z podglądem podstawowych opcji do zmiany sposobu wyświetlania obrazka.

Takim oto sposobem mamy nasz pierwszy automatyczny zrzut ekranu 😉 Teraz możemy zacząć go ulepszać.

Umiemy już tworzyć screenshoty, ale sposób ich robienia znacznie odbiega od tego co chcieliśmy osiągnąć. Zrzut ekranu będzie robiony zawsze a my chcielibyśmy aby był tworzony jedynie w momencie kiedy nasz test zakończy się niepowodzeniem. Jak to osiągnąć?

Możemy tutaj zastosować wcześniej poznaną konstrukcję try… except.

8 komentarzy

    1. Zazwyczaj przy tworzeniu projektu wskazane jest stworzenie dla niego własnego i nowego venv, chociaż jeśli np. chcesz reuzyć istniejący venv, to również możesz go wskazać 🙂 Tu należy jednakże uważać gdy więcej niż jeden projekt korzysta z danego venv – mogą pojawić się konflikty, niezgodności paczek i trudności w tworzeniu requirements.txt 😉

      PS. To nie spam a normalne pytanie 😉

      Krzysiek Kijas Krzysiek Kijas
  1. ok znalazlem przyczyne przy tworzeniu projektu zaznaczylem new environment using Virtualvenv nie wiem czy tak mialo byc ? odnosnie ‘ BasicScreenshotTests wraz z własnym venv’ a moj venv jest czysty i to chyba generowalo ten blad.

    Avatar Dawid Kowalczyk
    1. Tak, w tym przypadku tworzone jest nowe, czyste środowisko Pythona w katalogu (domyślnie) venv w projekcie. W takim przypadku wystarczy tylko doinstalować brakujące pakiety (albo przez opcje projektu i interpretra albo bezpośrednio ze skryptów). Później mając środowisko tylko z wymaganymi paczkami można w prosty sposób przenosić je w inne miejsca – natomiast informacje o pakietach – za pomocą pliku requirements.txt 😉

      Krzysiek Kijas Krzysiek Kijas
  2. zmienilem konfiguracje i dostaje
    Traceback (most recent call last):
    File “C:/Projects/BasicScreenshotTests/basic_screenshot_tests.py”, line 2, in
    from selenium import webdriver
    ModuleNotFoundError: No module named ‘selenium’

    a kod jest ten sam, czy to moze byc problem z importem selenium?

    Avatar Dawid Kowalczyk
    1. Tutaj wygląda na to, że konfiguracja nie korzysta z venv, który miał zainstalowaną paczkę selenium a np. z głównego Pythona systemowego. Sprawdź proszę w konfiguracji – tam jest opcja Python Interpreter – zobacz czy jest ustawiona na Pythona z venv czy systemowego 🙂

      Krzysiek Kijas Krzysiek Kijas
  3. Witam panowie nie wiem czemu ale mi sie nie uruchamia okno przegladarki dostaje exit code 0 brak pliku ze screenshotem. Czy to moze byc spowodowane venv?

    
    import unittest
    from selenium import webdriver
    
    
    class BasicScreenshotTests(unittest.TestCase):
    
        def setUp(self) :
            self.base_url = 'https://antoogle.testoneo.com/'
            self.driver = webdriver.Chrome(executable_path=r"C:\TestFiles\chromedriver.exe")
    
        def tearDown(self) :
            self.driver.quit()
    
        def test_open_antoogle(self) :
            self.driver.get(self.base_url)
            self.driver.get_screenshot_as_file("screenshot.png")
            self.assertEqual('The Antoogle Search Page', self.driver.title,
                             f'Expected title differ from actual for page url: {self.base_url}')
    
    
    Avatar Dawid Kowalczyk
    1. Hej,
      Tu bardziej bym szukał przyczyny w sposobie uruchamiania i konfiguracji – wynik wskazuje na to, ten skrypt uruchamiany jest jak zwykły skrypt a nie klasa testowa za pomocą runnera PyCharma.

      Krzysiek Kijas Krzysiek Kijas

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *