Selenium
Tags: python, selenium, beginners
Published: 2023-04-07 09:57:38

- **Selenium** is an open-source testing tool that is widely used for automating web browsers. 
- It provides a suite of tools for automating web applications for testing purposes.

# Why Selenium?

- There are various other tools for automating web browsers such as **Appium, Robot framework, Katalon Studio, Cypress, Jmeter, SoapUI** etc. 
- In recent years, selenium gained popularity because of the following:
    
    - Supports multiple programming languages such as *Java, Python, C#, Ruby, JavaScript, and more.*

    - Supports multiple browsers such as *Chrome, Firefox, Edge, Safari, and more.*

    - Supports various frameworks and tools for test reporting and test management, such as *TestNG, JUnit, Maven, Jenkins, and more.*
    - It offers three main components:   
      1. Selenium ID
      2. Selenium WebDriver
      3. Selenium Grid.

    - Selenium IDE is a record and playback tool used for creating simple test cases in a browser.

    - Selenium WebDriver is a powerful automated testing tool that provides a programming interface to create and execute complex test cases.

    - Selenium Grid is a distributed testing tool that allows running tests in parallel on multiple machines and browsers simultaneously.

    - We will be mainly focusing on Webdriver. 

- **Note:** `Selenium 4 and above versions are used here. You should have prior knowledge of Python.`


# Get started with Selenium

- ## Install

    - Open the terminal and the below command:

        ```bash
        pip install selenium
        ```

    - The installation entirely depends on your usage. You can install it globally as well in your virtual environment.

    - Install the below package

        ```bash
        pip install webdriver-manager 
        ```
    - **Why web driver-manager?**
      1. The WebDriver Manager automates the process of downloading and configuring WebDrivers for different browsers, which reduces the effort required to manage multiple versions of WebDrivers manually.
    
    - Example:
        
        - **Firefox**

            ```Python
            #Firefox
            from selenium import webdriver
            
            from selenium.webdriver.firefox.service import Service as FirefoxService
            
            from webdriver_manager.firefox import GeckoDriverManager

            
            driver = webdriver.Firefox(service=FirefoxService(GeckoDriverManager().install()))
            ```
    - You can find the link in the reference section for different browsers.

# Basics of Selenium

## 1. Open the browser using Selenium.

- **driver** is the object instantiation in the web driver class.

- *The object *driver* will be used to perform various tasks.*

    ```Python
    # Chrome
    # import webdriver from selenium
    from selenium import webdriver
    
    from selenium.webdriver.chrome.service import Service as ChromeService
    
    from webdriver_manager.chrome import ChromeDriverManager

    
    # The below line of code opens up a browser.
    driver = webdriver.Chrome(service=ChromeService(ChromeDriverManager().install()))
    ```

## 2. Navigate to the URL in a browser

- **driver.get(url)** is a method to open the webpage in the browser. 

- **driver.forward()** moves forward into the browser's history if present.

- **driver.back()** moves back into the browser's history. 

- You can also open the `folder/file` in the browser by providing the path of the `folder/file` instead of url. 

    ```Python
    driver.get("http://www.python.org")
    
    driver.forward()
    
    driver.back()
    ```

## 3. Setting the browser size

- You can set a custom size/position, fullscreen or maximize the window of the browser.

    ```python
    #Maximise Window
    driver.maximize_window()

    #FullScreen
    driver.fullscreen_window()

    #Set Window Size
    driver.set_window_size(500,400)

    #Set Window Position
    driver.set_window_position(x=500,y=400)

    #Get Window Size
    print(driver.get_window_size())

    #Get Window Position
    window_pos= driver.get_window_position()
    print(window_pos)

    #Page refresh command
    driver.refresh()
    ```

 
## 4. Interaction with page

- To interact with the pages, or, more specifically, the HTML elements within a page. First of all, we need to find one. WebDriver offers several ways to find elements. For example, given an element defined as:

    ```HTML
    <input type="text" name="passwd" id="passwd-id" />
    ```

- You could find it using any of:

    ```python
    from selenium.webdriver.common.by import By

    element = driver.find_element(By.ID, "passwd-id")
    
    element = driver.find_element(By.NAME, "passwd")
    
    element = driver.find_element(By.XPATH, "//input[@id='passwd-id']")
    
    element = driver.find_element(By.CSS_SELECTOR, "input#passwd-id")
    ```
- Use devtools to get the *Id, Name, Xpath or CSS_Selector.* These are often refferred as locators.

- After finding the element various operations can be performed on the elements such as `click`, `drag and drop`, `hold`, `hover`, `text` inside the element, `clear` the text, `toggle`, `select`.

- For instance, we will see the common actions performed on the elements.
    
    ```python
    element.click() # Performs a click on the element 
    
    element.send_keys('some-text') # Adds a text inside the input element
    
    element.clear() # Clears the text in the input element
    ```
- Perform a drag and drop

    ```python
    from selenium.webdriver import ActionChains
    
    element = driver.find_element(By.NAME, "source")
    target = driver.find_element(By.NAME, "target")
    
    
    action_chains = ActionChains(driver)
    action_chains.drag_and_drop(element, target).perform()
    ```
    - **BONUS:** *`While using actionchains() class always use .perform() at the end to perform the specific action. Actionchains() are used to trigger the mouse events in the browser. If you forget to write .perform(), the mouse events will fail to run. Although it won't through an error, you will not be able to use the mouse events`*

- Moving between windows

    - How do you know the window name?
    
      - Take a look at the javascript or link that opened it:

        ```HTML
        <a href="somewhere.html" target="windowName">Click here to open a new window</a>     
```

```python
driver.switch_to.window("windowName")
```
- Alternatively, you can also find by **driver.window_handles**

- **driver.window_handles** returns a list with hashcodes of the window, pass the hashcode instead of `windowName` in the above code. If you are not comfortable with hashcodes then feel free to use the above method.

    - **BONUS:** *` At times your browser will open a new tab. If you locate that element in the browser without changing the current handle of the browser then it will raise an error. So it is important that when your browser opens a new tab and if you want to work with the element in that tab then  switch to that window.`* 

# Waits

- When a page is loaded by the browser, the elements within that page may load at different time intervals. This makes locating elements difficult: if an element is not yet present in the DOM, a locate function will raise an ElementNotVisibleException exception.

- This is where wait comes into the picture to resolve this issue.

- There are two types of wait:
    1. Implicit wait
    2. Explicit Wait

- An implicit wait tells WebDriver to poll the DOM for a certain amount of time when trying to find any element (or elements) not immediately available. The default setting is 0 (zero). Once set, the implicit wait is set for the life of the WebDriver object.

    ```python
    from selenium import webdriver

    driver = webdriver.Firefox()
    
    driver.implicitly_wait(10) # seconds
    
    driver.get("http://somedomain/url_that_delays_loading")
    
    myDynamicElement = driver.find_element_by_id("myDynamicElement")
    ```

- An explicit wait is a code you define to wait for a certain condition to occur before proceeding further in the code. WebDriverWait in combination with ExpectedCondition is one way this can be accomplished.

    ```python
    from selenium import webdriver
    from selenium.webdriver.common.by import By
    from selenium.webdriver.support.wait import WebDriverWait
    from selenium.webdriver.support import expected_conditions as EC

    driver = webdriver.Firefox()
    driver.get("http://somedomain/url_that_delays_loading")
    
    element = WebDriverWait(driver, 10).until(
        EC.presence_of_element_located((By.ID, "myDynamicElement"))
    )
    ```

- In the code above, Selenium will wait for a maximum of 10 seconds for an element matching the given criteria to be found. If no element is found in that time, a TimeoutException is thrown. By default, WebDriverWait calls the ExpectedCondition every 500 milliseconds until it returns success. ExpectedCondition will return true (Boolean) in case of success or not null if it fails to locate an element.

- As we are moving towards the end of this post, you need to close the browser. 
    ```python
    # Closes the current session
    driver.close()

    # Closes all the session
    driver.quit()
    ```
# Conclusion

- *This is not the end of selenium. There are various other resources to know about selenium.*
- *The above content provided is solely based on getting a basic understanding of selenium.*
- *For more details see the references sections.*

# References:

- [How selenium came to existence?](https://selenium-by-arun.blogspot.com/2017/05/history-of-selenium.html)
- To know more about selenium, read the below documentation:
    
    - [Selenium](https://www.selenium.dev/documentation/overview/)

    - [Selenium with python](https://selenium-python.readthedocs.io/installation.html)

 - To know more about [Webdriver-manager](https://pypi.org/project/webdriver-manager/).