Search code examples
python-3.xseleniumselenium-webdriverpycharmscreenshot

Creating a function or class in python to take screenshots with different names for each web element?


I am new to automated browser testing using selenium webdriver (Python 3). The following method I am already using for testing and taking screenshots:

from selenium import webdriver
from selenium.webdriver.support.events import EventFiringWebDriver
from selenium.webdriver.support.events import AbstractEventListener
import unittest

class ScreenshotListener(AbstractEventListener):
    def on_exception(self, exception, driver):
        driver.get_screenshot_as_file("C:/Error.png")

class Test1_Chrome(unittest.TestCase):
    def setUp(self):
        self.driver = webdriver.Chrome()                    # Set chrome browser
        self.driver1 = EventFiringWebDriver(self.driver, ScreenshotListener())
        self.driver.maximize_window()                       # Maximize window
        time.sleep(0.30)                                    # Wait 30 seconds

    def test_port(self):
        driver = self.driver1
        driver.get("http://")              # Opens url into chrome
        driver.get_screenshot_as_file("C:/Chrome_screenshots/Screenshot1.png")
        driver.find_element_by_css_selector("a[name*='']").click()
        driver.get_screenshot_as_file("C:/Chrome_screenshots/Screenshot2.png")
        driver.find_element_by_css_selector("b[name*='']").click()
        driver.get_screenshot_as_file("C:/Chrome_screenshots/Screenshot3.png")
        driver.find_element_by_css_selector("a[href*='']").click()
        driver.get_screenshot_as_file("C:/Chrome_screenshots/Screenshot4.png")

    def tearDown(self):
        time.sleep(2)
        driver = self.driver1
        driver.close()

class Test2_IE(unittest.TestCase):
    def setUp(self):
        self.driver = webdriver.Ie()                    # Set IE browser
        self.driver2 = EventFiringWebDriver(self.driver, ScreenshotListener())
        self.driver.maximize_window()                       # Maximize window
        time.sleep(0.30)                                    # Wait 30 seconds

    def test_port(self):
        driver = self.driver2
        driver.get("http://")              # Opens url into IE
        driver.get_screenshot_as_file("C:/IE_screenshots/Screenshot1.png")
        driver.find_element_by_css_selector("a[name*='']").click()
        driver.get_screenshot_as_file("C:/IE_screenshots/Screenshot2.png")
        driver.find_element_by_css_selector("b[name*='']").click()
        driver.get_screenshot_as_file("C:/IE_screenshots/Screenshot3.png")
        driver.find_element_by_css_selector("c[href*='']").click()
        driver.get_screenshot_as_file("C:/IE_screenshots/Screenshot4.png")

    def tearDown(self):
        time.sleep(2)
        driver = self.driver2
        driver.close()

class Test3_Firefox(unittest.TestCase):
    def setUp(self):
        self.driver = webdriver.Firefox()                    # Set Firefox browser
        self.driver3 = EventFiringWebDriver(self.driver, ScreenshotListener())
        self.driver.maximize_window()                       # Maximize window
        time.sleep(0.30)                                    # Wait 30 seconds

    def test_port(self):
        driver = self.driver3
        driver.get("http://")              # Opens url into FireFox
        driver.get_screenshot_as_file("C:/FF_screenshots/Screenshot1.png")
        driver.find_element_by_css_selector("a[name*='']").click()
        driver.get_screenshot_as_file("C:/FF_screenshots/Screenshot2.png")
        driver.find_element_by_css_selector("b[name*='']").click()
        driver.get_screenshot_as_file("C:/FF_screenshots/Screenshot3.png")
        driver.find_element_by_css_selector("c[href*='']").click()
        driver.get_screenshot_as_file("C:/FF_screenshots/Screenshot4.png")

    def tearDown(self):
        time.sleep(2)
        driver = self.driver3
        driver.close()

if __name__ == '__main__':
    unittest.main()

Question: I want to create some loop or function for these screeenshots in such a way that : Saves all three browser element screenshots in a different folder with all different names. Example: ChromeSreenshots- Screenshot1, screenshot2, etc; IESreenshots- Screenshot1, screenshot2, etc; FirefoxSreenshots- Screenshot1, screenshot2, etc. How can I create such a function which I call into same or different python file?

The code I used already has "test_port(self)" function which is common for all three browsers except the screenshots(location and name). I want to use "test_port(self)" function by calling into all three browser tests but the problem is I want the screenshots to be in different locations and different names. I searched on web but did not found something good to solve this problem.


Solution

  • I look at your code and all three classes, Test1-3, are the same except for the browser instance. What that tells me is that you should instantiate the WebDriver instance before the test and pass it into the class. Once inside the class, you can detect what instance of WebDriver you are using (using .isinstance(), see this question) and then you can create a subfolder for Chrome vs Firefox vs IE, etc. and put all the screenshots in there. When you are done, you should have a folder for each browser that contains 4 screenshots, e.g. c:\chrome\ss1.png, c:\chrome\ss2.png, c:\ff\ss1.png, c:\ff\ss2.png, c:\ie\ss1.png, c:\ie\ss2.png, and so on.


    NOTE: python is not a language I program in so this code may not be optimal. Some sample code

    def test_port(self):
        driver = self.driver1
        driver.get("http://")              # Opens url
        path = get_screenshot_path()
        driver.get_screenshot_as_file(path + "Screenshot1.png")
        driver.find_element_by_css_selector("a[name*='']").click()
        driver.get_screenshot_as_file(path + "Screenshot2.png")
        driver.find_element_by_css_selector("b[name*='']").click()
        driver.get_screenshot_as_file(path + "Screenshot3.png")
        driver.find_element_by_css_selector("a[href*='']").click()
        driver.get_screenshot_as_file(path + "Screenshot4.png")
    
    def get_screenshot_path(self)
        path_root = "c:\"
        if isinstance(self.driver, webdriver.Chrome())
            # the driver is a instance of the Chrome driver
            path = path_root + "chrome\"
        if isinstance(self.driver, webdriver.Firefox())
            # the driver is a instance of the Firefox driver
            path = path_root + "firefox\"
        # create the subfolder if it doesn't exist
        os.makedirs(path, exist_ok=True)
        return path