nw.js chromedriver won't run from outside of the project folder - selenium

I am trying to set up automated tests on an nw.js based app using selenium-python with chromedriver and for practical reasons (frequent reinstallation...) I want to keep chromedriver separated from the rest of the files in another folder. My tests work only when the chromedriver is located at the same folder as the rest of the project (along with nw.exe). If I try to place it anywhere else and alter paths with 'binary_location', 'chrome_driver_binary' and 'add_argument' accordingly, I always end up with exceptions such as
selenium.common.exceptions.WebDriverException: Message: unknown error:
cannot find Chrome binary
or
selenium.common.exceptions.WebDriverException: Message: unknown error:
Failed to create a Chrome process
Nw.js documentation wasn't helpful as it only says the following:
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
chrome_options = Options()
chrome_options.add_argument("nwapp=/path/to/your/app")
driver = webdriver.Chrome(executable_path='/path/to/nwjs/chromedriver', chrome_options=chrome_options)
Thanks in advance for any ideas.

I was able to do this but I used ruby. It should be possible to translate to python.
Also I'm running Ubuntu 20.04. No idea if this will all work in Windows.
chrome_options.add_argument("nwapp=/path/to/your/app")
This line doesn't specify, but the nwapp should be a directory.
If you build your app using phoenix builder, then you probably have a line like this in package.json:
"package:linux": "npm run build:prod && build --tasks linux-x64 --mirror https://dl.nwjs.io/ .",
For me, this command creates a directory called packages/myapp-0.0.1-linux-x64
Inside of there you should see an executable "myapp" and the manifest "package.json"
The nwapp= line should point to this directory. It will use the manifest file to get the app name. In ruby that looks like this:
myapp_dir = File.join(root_dir, 'packages', 'myapp-0.0.1-linux-x64')
chrome_options.add_argument("nwapp=" + myapp_dir)
executable_path='/path/to/nwjs/chromedriver'
When you install nw.js with npm, it will create a directory tree: node_modules/nw/nwjs Inside that directory is the chromedriver executable.
The "executable_path" is the full path to chromedriver executable. In ruby, it looks like this:
chromedriver_path = File.join(root_dir, 'node_modules', 'nw', 'nwjs', 'chromedriver')
Selenium::WebDriver::Chrome::Service.driver_path = chromedriver_path
#driver = Selenium::WebDriver.for :chrome, options: chrome_options
Ruby does everything relative to where you invoke it, so I added a script in the root of my nw.js app and then added this line to package.json:
"e2e": "ruby ./e2e.rb"
Then this runs via npm run e2e

Related

Is there any selenium/python script for the Screen Recording?

I want to record the screen by using selenium in python, I searched for these, but I only get results for java, and for the screenshots. Please let me know if there is any script by which I can record the screen.
you need record the whone screenshot? try this library
and try this code:
from clicknium import clicknium as cc, locator, ui
cc.get_screenshot("D:\\test.jpg")
Try this, very popular framework for eg. java or python etc.
in cmd line : pip install allure-pytest
go here: https://docs.qameta.io/allure/
section 2.1. Installing a commandline
download the newest version for eg. windows xxx.zip
copy path of bin folder eg: D:\Drivers\allure-2.18.1\bin
and paste it to Environment Variables > find 'Path' and edit it> add new path with bin path.
to Your test.py file:
import allure
from allure_commons.types import AttachmentType
and add it at the end of Your test in eg.: assertion statement
example:
method_name = self.driver.find_element(By.XPATH, "xxx").text
if method_name == 'some text':
assert True
else:
allure.attach(self.driver.get_screenshot_as_png(), name="test_name",
attachment_type=AttachmentType.PNG)
assert False
In IDE terminal or cmd do this:
pytest -v -s --alluredir="D:\projectPath\raport" Path/to/your/tests
then tests will be executed
in terminal do this to read raport wfrom test:
allure serve "D:\raport\Path"
with this allure framework You will have reports of tests with screenshots:

Webdriver Issue

I trying to use selenium in jupyter notebook on Firefox. I have installed the geckodriver in /usr/bin directory .When I run my code it says:
WebDriverException: Message: 'geckodriver' executable needs to be in PATH.
if I run the command %env PATH following output is displayed:
$PATH:/usr/bin/
from selenium import webdriver
browser = webdriver.Firefox()
I have even tried
browser=webdriver.Firefox(executable_path=r'/usr/bin/geckodriver')
Can somebody help me solve this?
I hope you are working with geckodriver on the local machine and providing the absolute path for the driver to run, This can be done automatically using webdriver-manager python
Advantages of using it are-
You don't have to give the path every time to run code.
Makes the code portable and easy to run on any machine without checking for geckodriver or chromedriver.
pip install webdriver-manager
Now the above code in the question can be changed to work simply with,
from selenium import webdriver
from webdriver_manager.firefox import GeckoDriverManager
driver = webdriver.Firefox(executable_path=GeckoDriverManager().install())
If the above doesn't help, try doing this.
autoinstaller for geckodriver-
pip install geckodriver-autoinstaller
from selenium import webdriver
import geckodriver_autoinstaller
geckodriver_autoinstaller.install() #checks for driver or install it. driver =
webdriver.Firefox() driver.get("python.org")
this worked fine for me, otherwise, try to give a full path after downloading the latest geckodriver binary file.
Try to implement this with a Maven project so you can add dependencies in the pom.xml file. so you dont have to give the path each time. Refer this article here.Its in java but will help.

Electron cannot access user data directory when using Selenium ChromeDriver

I am using Selenium with Robot Framework to run an Electron application. The application is built to read a configuration file from the user data directory. As far as I understand, this is the location where this file should be stored.
The electron main process reads the configuration file:
const localConfigFile = path.join(app.getPath('userData'), 'config.json');
const localConfig = fs.existsSync(localConfigFile) ? require(localConfigFile) : {};
The built production version works just fine and reads the file as expected, but when starting it from Robot using SeleniumLibrary, the file is not read. This leads me to believe it's a problem with Robot, Selenium or ChromeDriver.
Robot creates the webdriver using SeleniumLibrary:
Create Webdriver Remote desired_capabilities=${starting_parameters} command_executor=http://127.0.0.1:9515
Where starting parameters are simply:
{ "chromeOptions": {"binary": <binary_location> }}
Chromedriver is started as a separate process from /usr/bin/chromedriver where it has been installed and uses the default port 9515.
The versions that I am using are:
ChromeDriver 2.36.540471 (9c759b81a907e70363c6312294d30b6ccccc2752)
"electron": "^6.0.2"
"electron-builder": "^21.2.0"
robotframework==3.2.1
robotframework-seleniumlibrary==3.3.1
Ubuntu 18.04.4 LTS
Experienced the same problem. Finally changing the Chromedriver's user-data-dir argument to Electron's userDataDir solved the problem.
options.add_argument('--user-data-dir=' + str(app_config_path()))
I found out the problem by using Spectron and logging the Electron main console. In general I would advice using Spectron instead of Robot to test Electron apps.
The issue is that the user data directory was not the same as the Electron default. When running the application through Chromedriver, the user data directory is changed to /tmp/somethingsomething so naturally the file under ~/.config/app-name was not found.
My solution was to use Electron'ss application data directory instead:
app.getPath('appData')
By default this is one directory up from the user data directory, but remains the same when running through Chromedriver.

How do I install selenium for Atom IDE?

When I try my code in the Atom IDE.
from selenium import webdriver
br = webdriver.Firefox()
br.get('https://www.facebook.com/login/')
email = br.find_element_by_id('email')
email.send_keys('7021038678')
pas = br.find_element_by_id('pass')
pas.send_keys('welcome')
pas.submit()
I get an error saying this:
selenium.common.exceptions.WebDriverException: Message: 'geckdriver.exe' executable needs to be in PATH.
I did pip install --user selenium in the console command in Atom. I've looked at other posts about this, however I'm not sure how I would fix it with the Atom IDE since I'm using Atom for Python instead of the Python IDE.
You can also pass the path to Geckodriver during initializatin
br = webdriver.Firefox('#your_browser_path')
What you can do is:
from selenium import webdriver
from webdriver_manager.firefox import GeckoDriverManager
driver = webdriver.Firefox(executable_path=GeckoDriverManager().install())
It will try to install GeckoDriver for Firefox every time.
Note: First you have to install the package using:
pip install webdriver-manager
I don't believe this is an issue with Selenium. You should read what the error says: 'geckdriver.exe' which is a FireFox webdriver selenium uses to run tests.
All you need to do is install geckodriver and make a reference to the file directory in your PATH in your systems environment variables

Program using selenium fails after building with cx_freeze

I'm developing an automatic web tester using Selenium (v2.37.2). Program works properly until I run the test built with cxfreeze (there is also tkinter gui).
there is the init function
def initDriver(self):
if self.browser == FIREFOX:
profile = webdriver.FirefoxProfile(profile_directory=self.profile);
self._driver = webdriver.Firefox(firefox_profile=profile)
elif self.browser == CHROME:
self._driver = webdriver.Chrome(self.executable, chrome_options=profile)
elif self.browser == IEXPLORER:
self._driver = webdriver.Ie(self.executable)
Now when I build it using Cx_freeze I get this error
method redirectToBlank(...) calls initDriver(..) as the first thingSo how I pack the .xpi file to the library.zip file - which option in setup.py I have to use? And do I even have to this?
And the second strange thing is, that the other browsers work fine, when I execute the .exe file in by clicking on its icon, but when I run it from command line, I get errors even for chrome and IE. (Sorry that the traceback isn't complete)
All paths are relative from the executed file (no matter from where you run it),
Thank you for any ideas to solve this problem.
(method redirectToBlank(...) calls initDriver(..) as the first thing)
First issue solved
It's problem with selenium - FirefoxProfile - class, which tries to load webdriver.xpi as a normal file, but selenium pack all libraries to a zip file, so selenium can't find it.
Even forcing cx_freeze in setup file to add webdriver.xpi to a proper directory in zip won't help.
It is necessary to edit FirefoxProfile (in firefox_profile module) class for example like this
def _install_extension(self, addon, unpack=True):
"""
Installs addon from a filepath, url
or directory of addons in the profile.
- path: url, path to .xpi, or directory of addons
- unpack: whether to unpack unless specified otherwise in the install.rdf
"""
if addon == WEBDRIVER_EXT:
# altered lines
import sdi.env
WEBDRIVER_SUBSTITUTE = "path/to/unpacked/webdrive.xpi"
addon = os.path.join(os.path.dirname(__file__), WEBDRIVER_SUBSTITUTE)
# Original lines:
# addon = os.path.join(os.path.dirname(__file__), WEBDRIVER_EXT)
< the rest of the method >
Issue 2
OSError: win error 6: the handle is invalid problem wasn't caused by either cxfreeze or selenium. I run the final exe file from git bash. There's the problem. For some reason git bash doesn't open stdin for the program and that's why it fails. When I run it in standard windows command line, everything is ok or if i run it from git bash like program.exe < empty_file
what i did was remove selenium form packages list.
and put it inside includefiles, then it works.
like this :
includefiles = [(seleniumPackage,'')]
...
options = {'build_exe': {'includes':includes,
'excludes':excludes,
'optimize':2,
'packages':packages,
'include_files':includefiles,
...