Chromedriver test work locally and on CI CD env python - python

What I have: CURRENT_BROWSER=chrome in Win Environments
def before_scenario(context, scenario):
use_fixture(browser, context)
def after_scenario(context, scenario):
context.cache.clear()
context.driver.quit()
#fixture
def browser(context):
browser_type = os.getenv('CURRENT_BROWSER', 'chrome')
if browser_type is None:
raise Exception(f"Unable to identify test browser which is {browser_type}")
if browser_type == 'chrome':
chrome_options = webdriver.ChromeOptions()
chrome_options.add_argument('--headless')
# chrome_options.add_argument('--incognito')
context.driver = webdriver.Chrome(desired_capabilities=chrome_options.to_capabilities())
if browser_type == 'firefox':
pass
yield context.driver
What I need is: the answer how to deal with the chromedriver on CI CD (azureDevops) should I also put ENV variable similar to Browser in to the PATH and do the same on CI CD or there is different way to deal with chrome driver. I need above code will work locally and on CI CD and I never did that before. Locally I use above code + chromedriver.exe added in to project structure

If you are using a Microsoft-hosted agent: windows-latest, windows-2019 or vs2017-win2016, the Chrome Driver 87.0.4280.88 is already installed.
If you want to use another version of Chrome Driver, you can download it using npm:
- script: npm install chromedriver --chromedriver_version=LATEST
Click this document for detailed information.
If you are using a Self-hosted agent and the agent is on a machine that has already downloaded the Chrome Driver and configured PATH, you can use Chrome Driver just as you work on your own machine.

Related

Why in Azure pipelines driver path is not correct and executed like linux instead of win

I want to execute my auto tests in Azure pipeline but I got the following error:
selenium.common.exceptions.WebDriverException: Message: unknown error: no chrome binary at C:\Program Files\Google\Chrome\Application\chrome.exe
Bu chrome.exe is located by this path and there is should not be any issue. So, as per my initial investigation the issue related to the fact that in Azure pipelines it is trying to get chromedriver by following path:
WDM:logger.py:16 Current google-chrome version is 102.0.5005
INFO WDM:logger.py:16 Get LATEST chromedriver version for 102.0.5005 google-chrome
INFO WDM:logger.py:16 Driver [/home/vsts/.wdm/drivers/chromedriver/linux64/102.0.5005.61/chromedriver] found in cache
As you can see there is indicated linux64, but look up the below logs from my local machine.
Locally if I am trying to run the same test cases I see the different path and everything is running and passed correctly. Since there is win32, not linux64.
[WDM] - Current google-chrome version is 102.0.5005
[WDM] - Get LATEST chromedriver version for 102.0.5005 google-chrome
[WDM] - Driver [C:\Users\AYTAN\.wdm\drivers\chromedriver\win32\102.0.5005.61\chromedriver.exe] found in cache
So I can't understand why on my local machine the path to chromedriver is correct but in Azur pipelines it is not correct. How I can fix it? Maybe I can indicate it directly in my code? My Python code is below:
#pytest.fixture
def get_chrome_options():
options = chrome_options()
options.add_argument('chrome')
options.binary_location = r"C:\Program Files\Google\Chrome\Application\chrome.exe"
options.chrome_driver_binary = r"C:\Users\USER\.wdm\drivers\chromedriver\win32\102.0.5005.61\chromedriver.exe"
options.add_argument("--start-maximized")
options.add_argument("--no-sandbox")
options.add_argument("--disable-dev-shm-usage")
options.add_experimental_option("excludeSwitches", ["enable-automation"])
options.add_experimental_option('useAutomationExtension', False)
return options
#pytest.fixture
def get_webdriver(get_chrome_options):
options = get_chrome_options
driver = webdriver.Chrome(options=options, service=Service(ChromeDriverManager().install()))
return driver
Give relative path instead the entire path that might help.
for eg:
./testapp/console-app/chrome.exe
You can also give absolute path too but here the root directory
changes it becomes Build.SourcesDirectory . It is at this directory
where the source code is downloaded.
for eg:
$(Build.SourcesDirectory)/testapp/console-app/chrome.exe
Reference:
Directories in azure devops

Selenium crashing (chrome & firefox) within a flask route on ubuntu 20.04

Running Ubuntu 20.04 LTS server
Trying to save a screenshot via selenium within a flask route.
Issue is no matter what I try it crashes.
Using --headless
#api.route('/image/<path:encoded_url>.png')
def generate_image(encoded_url):
"""
Returns an image (PNG) of a URL. The URL is encoded in the path of the image being requested.
"""
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
options = Options()
options.headless = True
options.add_argument("--disable-gpu")
options.add_argument("--disable-dev-shm-using")
driver = webdriver.Chrome(f"{os.getcwd()}/chromedriver", options=options)
url = urllib.parse.unquote_plus(encoded_url)
driver.get(url if "http" in url else "https://" + url)
driver.set_window_size(1200, 630)
while True:
x = driver.execute_script("return document.readyState")
if x == "complete":
break
driver.save_screenshot("screen.png")
driver.close()
return send_file("screen.png", mimetype='image/png')
I've tried everything but firefox exits with error 127 (not much online regarding this)
selenium.common.exceptions.WebDriverException: Message: Process unexpectedly closed with status 127
I've tried running with Xvfb with no luck.
Ok, so after trying a whole load of options it turns out the issue was with my setup of gunicorn.
go to
cd /etc/systemd/system/
open the service you made for guinocorn
sudo nano {servicename}
The issue was the Environment line
Originally I has it as this:
Environment="PATH=/home/ubuntu/retrotex/environment/bin"
But once I changed it to the below everything worked:
Environment="PATH=/home/ubuntu/retrotex/environment/bin:/usr/bin:/bin"
It seems that flask didn't have access to the folders needed to run chome or selenium.
Make sure you run the below to reload the service after
sudo systemctl daemon-reload
sudo systemctl restart {service_name}
What a waste of a day.

How to setup chromedriver in jenkins for selenium-python script?

I am using the following code to run my script in local machine
from seleniumwire import webdriver
import pytest
from selenium.webdriver.chrome.options import Options
import time
import allure
class Test_main():
#pytest.fixture()
def test_setup(self):
# instantiate browser
chrome_options = Options()
chrome_options.add_argument('--start-maximized')
chrome_options.add_argument('--headless')
self.driver = webdriver.Chrome(executable_path=r"D:/Python/Sel_python/drivers/chromedriverv86/chromedriver.exe", chrome_options=chrome_options)
# terminate script
yield
self.driver.close()
self.driver.quit()
print("Test completed")
##Remaining functions/test cases followed. Not adding the entire script here
I pushed this code onto git and then tried to run the same in jenkins using following build commands:
cd "D:\Python\Sel_python\Pytest"
pip install -r requirements.txt
pytest Test_Tracking_code_scripts.py -s -v
But then jenkins threw an error that chromedriver cannot be located. My questions are:
Do I need to upload chromedriver.exe as well into my git repository
Does jenkins have its own chrome browser? If yes how do I use it and what path has to be specified?
I am new to jenkins, please help me out here
Check chrome version in Jenkins system
Download chrome driver based on Jenkins system from here
Copy the chrome driver to "C:/drivers/" in Jenkins server (As C driver is common to all windows system)
update code as below
self.driver = webdriver.Chrome(executable_path=r"D:/Python/Sel_python/drivers/chromedriverv86/chromedriver.exe", chrome_options=chrome_options)
as
self.driver = webdriver.Chrome(executable_path=r"C:/drivers/chromedriver.exe", chrome_options=chrome_options)
Let me know if you face any issues with this.
NOTE:
In local system please move driver to "C:/driver" so that both remote and local system path is same.
If chrome version is updated in local or remote, please update chrome driver version i.e. chromedriver.exe
I found the solution. My code was missing the chrome binary path. Adding the same as an Options() argument resolved the error.
Sharing the updated patch of code:
from seleniumwire import webdriver
import pytest
from selenium.webdriver.chrome.options import Options
import time
import allure
class Test_main():
#pytest.fixture()
def test_setup(self):
# initiating browser
chrome_options = Options()
chrome_options.binary_location=r"C:\Users\libin.thomas\AppData\Local\Google\Chrome\Application\chrome.exe"
chrome_options.add_argument('--start-maximized')
chrome_options.add_argument('--headless')
self.driver = webdriver.Chrome(executable_path=r"D:/Python/Sel_python/drivers/chromedriver v86/chromedriver.exe",options=chrome_options)
# terminate script
yield
self.driver.close()
self.driver.quit()
print("Test completed")
#test cases followed below

How to properly use selenium with geckodriver and firefox with python on Ubuntu?

I am trying to use the geckodriver with firefox and selenium on my Ubuntu machine. This is the code I have so far:
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
from selenium.webdriver.firefox.options import Options
from selenium.webdriver.common.keys import Keys
from selenium import webdriver
#path where browser is installed
binary = '/usr/bin/firefox'
options = webdriver.FirefoxOptions()
options.binary = binary
options.add_argument('start-maximized')
options.add_argument('--headless')
cap = DesiredCapabilities().FIREFOX
cap["marionette"] = False
path_to_driver = "/home/andrea/geckodriver"
# run firefox webdriver from executable path
driver = webdriver.Firefox(firefox_options=options, capabilities=cap, executable_path = path_to_driver)
#driver = webdriver.Firefox(capabilities=cap, executable_path = path_to_driver)
driver.get("https://www.amboss.com/us/account/login")
Despite that I am getting the following error:
selenium.common.exceptions.WebDriverException: Message: Can't load the profile.
Possible firefox version mismatch. You must use GeckoDriver instead for Firefox 48+. Profile Dir: /tmp/tmpuigrk9f7 If you specified a log_file in the FirefoxBinary constructor, check it for details.
The firefox version which I work with is:
Mozilla Firefox 68.0.2
Does anyone have any idea as to how I could go about fixing this?
Step1: Install Selenium
Type in Terminal(in Ubuntu) or in Command Prompt(in Windows)
$pip install selenium
Step2: Download Geckodriver
In order to work with Selenium there should be an executable called 'Gecko Driver' installed.
Download Gecko Driver from the following page:
https://github.com/mozilla/geckodriver/releases
Step3: Install Gecko Driver
Latest version for Windows:
https://github.com/mozilla/geckodriver/releases/download/v0.26.0/geckodriver-v0.26.0-win64.zip
Latest version for Ubuntu:
https://github.com/mozilla/geckodriver/releases/download/v0.26.0/geckodriver-v0.26.0-linux64.tar.gz
Setup Gecko Driver For Windows:
Extract the zip file and move the geckodiver.exe executable file to any location which is already in Path variable(For Example you can move it to Python path location)
Unless add the path of 'geckodriver.exe' to the Path variable
Setup Gecko Driver For Ubuntu:
Open Terminal
Ctrl+Alt+T
move directory to the location where tar file is downloaded
Usually it will be in Downloads. so type $ cd Downloads
Unzip the tar file
eg:
$sudo tar -xvf filename.tar.gz
In my case it is:
$sudo tar -xvf geckodriver-v0.26.0-linux64.tar.gz
Move the geckodriver executable file to the '/usr/local/bin' location
$sudo mv geckodriver /usr/local/bin/
Move the directory to '/usr/local/bin/'
$cd /usr/local/bin/
Now make executable permission for 'geckodriver' executable file
$sudo chmod +x geckodriver
Now type 'geckodriver' in Terminal
geckodriver
If Gecko Driver is not working still then add its path
$export PATH=$PATH:/usr/local/bin/geckodriver
Now it is ready to work with selenium
Sample Code
Some sample codes are here:
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support import ui
driver = webdriver.Firefox()
driver.get('https://www.google.com/')
page_url=driver.find_elements_by_xpath("//a[#class='content']")
all_title = driver.find_elements_by_class_name("title")
title = [title.text for title in all_title]
print(title)
This error message...
selenium.common.exceptions.WebDriverException: Message: Can't load the profile.
Possible firefox version mismatch. You must use GeckoDriver instead for Firefox 48+. Profile Dir: /tmp/tmpuigrk9f7 If you specified a log_file in the FirefoxBinary constructor, check it for details.
...implies that there was a mismatch between the GeckoDriver and Firefox version while initiating/spawning a new WebBrowsing Session i.e. Firefox Browser session.
Your main issue is the incompatibility between the version of the binaries you are using as follows:
You are using Mozilla Firefox v68.0.2
Your Selenium Client version is is unknown to us.
Your GeckoDriver version is unknown to us.
However as you are using Mozilla Firefox v68.0.2, using GeckoDriver is mandatory and while you use GeckoDriver you can't set the capability marionette as False.
You can find a detailed discussion in How can Geckodriver/Firefox work without Marionette? (running python selenium 3 against FF 53)
Solution
Upgrade Selenium to current levels Version 3.141.59.
Upgrade GeckoDriver to current GeckoDriver v0.24.0 level.
GeckoDriver is present in the specified location.
GeckoDriver is having executable permission for non-root users.
Upgrade Firefox version to Firefox v68.0.2 levels.
Clean your Project Workspace through your IDE and Rebuild your project with required dependencies only.
If your base Web Client version is too old, then uninstall it through Revo Uninstaller and install a recent GA and released version of Web Client.
Take a System Reboot.
Execute your Test as a non-root user.
Always invoke driver.quit() within tearDown(){} method to close & destroy the WebDriver and Web Client instances gracefully.
Outro
GeckoDriver, Selenium and Firefox Browser compatibility chart
If you want to use Firefox with Selenium, you need to import e Firefox Profile. You can use your own Profile through the following steps :
Locate the Firefox Profile directory
You have to specify the absolute path of the Firefox Profile directory when you initiate the webdriver.
from selenium import webdriver
profile = webdriver.FirefoxProfile(*path to your profile*)
driver = webdriver.Firefox(firefox_profile=profile)

Unknown error: Chrome failed to start: exited abnormally

I am getting this error when I run my tests with Selenium using chromedriver.
selenium.common.exceptions.WebDriverException: Message:
unknown error: Chrome failed to start: exited abnormally
(Driver info: chromedriver=2.9.248316,platform=Linux 3.8.0-29-generic x86)
I did download google-chrome stable and also chromedriver and have used this code to start the browser.
driver = webdriver.Chrome('/usr/local/bin/chromedriver')
Any suggestions anyone? Thanks.
For Linux :
Start the Display before start the Chrome. for more info click here
from pyvirtualdisplay import Display
display = Display(visible=0, size=(800, 800))
display.start()
driver = webdriver.Chrome()
To help debug this problem you can use the service_log_path and service_args arguments to the selenium webdriver to see output from the chromedriver:
service_log_path = "{}/chromedriver.log".format(outputdir)
service_args = ['--verbose']
driver = webdriver.Chrome('/path/to/chromedriver',
service_args=service_args,
service_log_path=service_log_path)
I was getting this same exception message and found two ways to get past it; I'm not sure if the OP's problem is the same, but if not, the chromedriver log will hopefully help. Looking at my log, I discovered that the chromedriver (I tried 2.9 down to 2.6 while trying to fix this problem) decides which browser to run in a very unexpected way. In the directory where my chromedriver is located I have these files:
$ ls -l /path/to/
-rwx------ 1 pjh grad_cs 5503600 Feb 3 00:07 chromedriver-2.9
drwxr-xr-x 3 pjh grad_cs 4096 Mar 28 15:51 chromium
When I invoke the chromedriver using the same python code as the OP:
driver = webdriver.Chrome('/path/to/chromedriver-2.9')
This leads to the exception message. In the chromedriver.log I found this message:
[1.043][INFO]: Launching chrome: /path/to/chromium ...
Unbelievable! The chromedriver is trying to use /path/to/chromium (which is not an executable file, but a directory containing source code) as the browser to execute! Apparently chromedriver tries to search the current directory for a browser to run before searching my PATH. So, one easy solution to this problem is to check the directory where the chromedriver is located for files/directories like chrome and chromium and move them to a different directory than the chromedriver.
A better solution is to explicitly tell selenium / chromedriver which browser to execute by using the chrome_options argument:
options = webdriver.ChromeOptions()
options.binary_location = '/opt/google/chrome/google-chrome'
service_log_path = "{}/chromedriver.log".format(outputdir)
service_args = ['--verbose']
driver = webdriver.Chrome('/path/to/chromedriver',
chrome_options=options,
service_args=service_args,
service_log_path=service_log_path)
The chromedriver.log now shows:
[0.999][INFO]: Launching chrome: /opt/google/chrome/google-chrome ...
as expected.
An alternative solution of using a virtual display is the headless mode.
from selenium import webdriver
chrome_options = webdriver.ChromeOptions()
chrome_options.add_argument('--no-sandbox')
chrome_options.add_argument('--window-size=1420,1080')
chrome_options.add_argument('--headless')
chrome_options.add_argument('--disable-gpu')
driver = webdriver.Chrome(chrome_options=chrome_options)
If using Linux make sure you are not running as root. That what gave me the error.
Someone already mentioned about --no-sandbox option, but to expand on it: make sure, it's the first option you pass:
System.setProperty("webdriver.chrome.driver",
Paths.get("setups", driverFolder, driverFile).toAbsolutePath().toString());
ChromeOptions options = new ChromeOptions();
Map<String, Object> prefs = new HashMap<>();
prefs.put("intl.accept_languages", "English");
options.setExperimentalOption("prefs", prefs);
options.addArguments("--no-sandbox");
options.addArguments("--disable-features=VizDisplayCompositor");
options.addArguments("--incognito");
options.addArguments("enable-automation");
options.addArguments("--headless");
options.addArguments("--window-size=1920,1080");
options.addArguments("--disable-gpu");
options.addArguments("--disable-extensions");
options.addArguments("--dns-prefetch-disable");
options.setPageLoadStrategy(PageLoadStrategy.NORMAL);
options.addArguments("enable-features=NetworkServiceInProcess");
DesiredCapabilities capabilities = DesiredCapabilities.chrome();
capabilities.setCapability("marionette", true);
capabilities.setCapability(ChromeOptions.CAPABILITY, options);
WebDriver driver = new ChromeDriver(capabilities);
driver.manage().timeouts().implicitlyWait(15, SECONDS);
driver.manage().timeouts().pageLoadTimeout(15, SECONDS);
When it was added after other options, I got the error.
You may be able to fix this issue by making sure your version of chromedriver is right for the version of Chrome you have installed, which you can check here. You will also need to remove your current version of chromedriver before installing the new one, as described in Delete Chromedriver from Ubuntu
This issue resolved using below steps
Install Xvfb
Centos 7 : yum install chromedriver chromium xorg-x11-server-Xvfb
update chrome driver
Centos 7 : wget https://chromedriver.storage.googleapis.com/2.40/chromedriver_linux64.zip
I was faced with the same issue and fixed it by installing Chrome in:
C:\Users\..\AppData\Local\Google\Chrome\Application
You can do this by running the Chrome Setup and saying no when prompted by the User Account Control.
I got the same error when I crawl something using scrapy + selenium + chrome driver on Centos 7,and the method of following url solved my problem.
yum install mesa-libOSMesa-devel gnu-free-sans-fonts
refer:https://bugs.chromium.org/p/chromium/issues/detail?id=695212
Another solution for selenium webdriver is X virtual frame buffer:
with Xvfb() as _:
timeout_request = ConfigTargetsManager.target_global_configs.get('timeout_request', 10)
driver = webdriver.Chrome(executable_path=ConfigTargetsManager.target_global_configs.get('chrome_browser_path',
'/usr/lib/chromium-browser/chromedriver'))
driver.get(url)
Ubuntu 22.04.
May be useful for someone.
I got this bug when trying to get selenium to work with a version of Brave (Deb) installed from the brave.com repository.
Additionally installed Brave from the snap image, added it:
options.add_argument('--remote-debugging-port=9224')
options.binary_location = '/snap/bin/brave'
This solved the problem.

Categories

Resources