How to attach to existing Browsers in Web Automation
Tags: tutorial, python, webdev, testing
Published: 2022-10-11 12:52:24

## Overview
For web automation, there are common scenarios containing end-to-end automation without human intervention, headless browser automation, and partial automation.

Partial automation means that not the entire business process is automated, and humans may operate some in advance due to security concerns, complex operations which are not repetitive but time-consuming, etc. In this automation case, the browser is opened, the human will do the relevant preparation work, and then the automation script will be executed for the repetitive part.

In this case, attaching the existing browser is necessary for the automation script to handle the same browser which human works on. We are introducing the browser attaching method for different automation libraries here, containing [Selenium](https://www.selenium.dev/), [Playwright](https://playwright.dev/), and [Clicknium](https://www.clicknium.com/).

## Selenium attaches to the existing browser
#Requirements
- Download ChromeDriver from [here](https://chromedriver.storage.googleapis.com/index.html). You need to select the same version of chromedriver.exe with your installed chrome browser, which you can see it by `chrome://version` in chrome browser.
- Place the chromedriver.exe in the same folder as Chrome.exe. For example, if your Chrome browser file path is `C:\Program Files\Google\Chrome\Application\chrome.exe`, then the chromedriver.exe could be accessed with `C:\Program Files\Google\Chrome\Application\chromedriver.exe`.
- The browser that needs to be attached should be started with argument --remote-debugging-port, and you also need to operate on this browser. The command looks like this:
"C:\Program Files\Google\Chrome\Application\chrome.exe" --remote-debugging-port=8888
- Notice that if there are other Chrome browsers running in the same time, it is better to close the others and keep the only one that you want to attach later, or the Selenium script might not successfully attach to the right browser, or the page that you want to automate may get refreshed when attaching.
## Code
The idea is to start a Chrome instance by specifying the option of `debugger_address`, the port in the address is what we specified in the command before. And then, get to the page where you want to run the Selenium automation script after attaching.
```python
from selenium import webdriver
from selenium.webdriver import ChromeOptions
from selenium.webdriver.chrome.service import Service
options = ChromeOptions()
options.debugger_address = "127.0.0.1:" + '8888'
browser = webdriver.Chrome(service=Service(executable_path="C:\\Program Files\\Google\\Chrome\\Application\\chromedriver.exe"), options=options)
browser.get("https://contoso.com/u/0/#in?compose=new")
```
## The playwright attaches to the existing browser
### Requirements
- Run playwright install to init the playwright prerequisites
- The browser that needs to be attached should be started with argument `--remote-debugging-port` , and you also need to operate on this browser. The command looks like this:
`"C:\Program Files\Google\Chrome\Application\chrome.exe" --remote-debugging-port=8888 `
- Notice that if there are other Chrome browsers running in the same time, it is better to close the others and keep the only one that you want to attach later. And if there are multiple windows opened from the browser started by the above command, it is better to keep one page with the Url that you want to automate to avoid attaching to a non-target page.  

### Code
The playwright provides two ways to attach to existing browsers: [connect](https://playwright.dev/python/docs/api/class-browsertype#browser-type-connect) and [connect_over_cdp](https://playwright.dev/python/docs/api/class-browsertype#browser-type-connect-over-cdp). The `connect` needs to work with `launchServer` in Node.js, so we will use `connect_over_cdp` in Python to manually start the Chrome browser. The code is as below:
```python
from playwright.sync_api import sync_playwright
with sync_playwright() as p:
    browser = p.chromium.connect_over_cdp("http://localhost:8888")
    default_context = browser.contexts[0]
    page = default_context.pages[0]
```


## Clicknium attaches to exsiting browser  
## Requirements
- Install [Clicknium VSCode Extension](https://marketplace.visualstudio.com/items?itemName=ClickCorp.clicknium) and Python module `pip install clicknium`. More about [Clicknium](https://www.clicknium.com/).
- Install the Clicknium browser extension. There are two ways of doing this:
- Install via Python:
```python
import clicknium as cc
cc.chrome.extension.install()
Install via VSCode extension UI:
```

- Notice that the browser extension needs to be enabled after installation.  
## Code
Clicknium provides two ways to `attach` existing browsers, attach and `attach_by_title_url`. The `attach` is to attach a browser by a web element specified in the target browser. The `attach_by_title_url` is to attach to a target browser by title or Url. This is more flexible if the target page element can be dynamically changed. The code is as below: (we may use wildcard * if part of the Url may change)
```python
from clicknium import clicknium as cc, locator
browser = cc.chrome.attach_by_title_url(ulr='https://contoso.com/u/0/in?id=*')
#browser.find_element(locator.hundun.img)
```
## Compare

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qrb9rmurpmm68tswk37r.png)


It is not easy to make attaching to the browser stable. If you have any suggestions on this, please feel free to leave a comment. Thanks.