I'm still a Python beginner, who wants to automate a tiny Electron app: "Piksel", with Selenium. Note: The source code below works with Firefox, Opera and Chrome browser contexts in other website testing projects... (of course without the chrome_options...)
I tried the following tutorial, but without luck: https://applitools.com/blog/automating-electron-applications-using-selenium
Instead of using Java I want to use Python and webriver.Remote... (Selenium server)
First I tried the common "Chromedriver", then a special flavor named "ChromeDriver for Electron" from here: https://github.com/electron/chromedriver
But, both attempts ended up with the same error, while "Piksel" was opened and closed after a timeout without to be able to do something (like finding elements, clicks etc.):
HOOK-ERROR in before_scenario: WebDriverException: Message: unknown error: Chrome failed to start: exited normally
(unknown error: DevToolsActivePort file doesn't exist)
(The process started from chrome location /home/***/opt/Piskel-0.14.0-64bits/piskel is no longer running, so ChromeDriver is assuming that Chrome has crashed.)
Build info: version: '3.141.59', revision: 'e82be7d358', time: '2018-11-14T08:25:53'
System info: host: '***', ip: '127.0.0.1', os.name: 'Linux', os.arch: 'amd64', os.version: '4.15.0-55-generic', java.version: '1.8.0_212'
Driver info: driver.version: unknown
remote stacktrace: #0 0x55f9ba5e85e9 <unknown>
Stacktrace:
at sun.reflect.NativeConstructorAccessorImpl.newInstance0 (NativeConstructorAccessorImpl.java:-2)
at sun.reflect.NativeConstructorAccessorImpl.newInstance (NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance (DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance (Constructor.java:423)
at org.openqa.selenium.remote.W3CHandshakeResponse.lambda$errorHandler$0 (W3CHandshakeResponse.java:62)
at org.openqa.selenium.remote.HandshakeResponse.lambda$getResponseFunction$0 (HandshakeResponse.java:30)
at org.openqa.selenium.remote.ProtocolHandshake.lambda$createSession$0 (ProtocolHandshake.java:126)
at java.util.stream.ReferencePipeline$3$1.accept (ReferencePipeline.java:193)
at java.util.Spliterators$ArraySpliterator.tryAdvance (Spliterators.java:958)
at java.util.stream.ReferencePipeline.forEachWithCancel (ReferencePipeline.java:126)
at java.util.stream.AbstractPipeline.copyIntoWithCancel (AbstractPipeline.java:499)
at java.util.stream.AbstractPipeline.copyInto (AbstractPipeline.java:486)
at java.util.stream.AbstractPipeline.wrapAndCopyInto (AbstractPipeline.java:472)
at java.util.stream.FindOps$FindOp.evaluateSequential (FindOps.java:152)
at java.util.stream.AbstractPipeline.evaluate (AbstractPipeline.java:234)
at java.util.stream.ReferencePipeline.findFirst (ReferencePipeline.java:464)
at org.openqa.selenium.remote.ProtocolHandshake.createSession (ProtocolHandshake.java:128)
at org.openqa.selenium.remote.ProtocolHandshake.createSession (ProtocolHandshake.java:74)
at org.openqa.selenium.grid.session.remote.RemoteSession$Factory.performHandshake (RemoteSession.java:147)
at org.openqa.selenium.grid.session.remote.ServicedSession$Factory.apply (ServicedSession.java:161)
at org.openqa.selenium.remote.server.ActiveSessionFactory.lambda$apply$12 (ActiveSessionFactory.java:180)
at java.util.stream.ReferencePipeline$3$1.accept (ReferencePipeline.java:193)
at java.util.stream.ReferencePipeline$11$1.accept (ReferencePipeline.java:373)
at java.util.stream.ReferencePipeline$2$1.accept (ReferencePipeline.java:175)
at java.util.Spliterators$ArraySpliterator.tryAdvance (Spliterators.java:958)
at java.util.stream.ReferencePipeline.forEachWithCancel (ReferencePipeline.java:126)
at java.util.stream.AbstractPipeline.copyIntoWithCancel (AbstractPipeline.java:499)
at java.util.stream.AbstractPipeline.copyInto (AbstractPipeline.java:486)
at java.util.stream.AbstractPipeline.wrapAndCopyInto (AbstractPipeline.java:472)
at java.util.stream.FindOps$FindOp.evaluateSequential (FindOps.java:152)
at java.util.stream.AbstractPipeline.evaluate (AbstractPipeline.java:234)
at java.util.stream.ReferencePipeline.findFirst (ReferencePipeline.java:464)
at org.openqa.selenium.remote.server.ActiveSessionFactory.apply (ActiveSessionFactory.java:183)
at org.openqa.selenium.remote.server.NewSessionPipeline.lambda$null$2 (NewSessionPipeline.java:66)
at java.util.stream.ReferencePipeline$3$1.accept (ReferencePipeline.java:193)
at java.util.stream.ReferencePipeline$2$1.accept (ReferencePipeline.java:175)
at java.util.Collections$2.tryAdvance (Collections.java:4717)
at java.util.stream.ReferencePipeline.forEachWithCancel (ReferencePipeline.java:126)
at java.util.stream.AbstractPipeline.copyIntoWithCancel (AbstractPipeline.java:499)
at java.util.stream.AbstractPipeline.copyInto (AbstractPipeline.java:486)
at java.util.stream.AbstractPipeline.wrapAndCopyInto (AbstractPipeline.java:472)
at java.util.stream.FindOps$FindOp.evaluateSequential (FindOps.java:152)
at java.util.stream.AbstractPipeline.evaluate (AbstractPipeline.java:234)
at java.util.stream.ReferencePipeline.findFirst (ReferencePipeline.java:464)
at org.openqa.selenium.remote.server.NewSessionPipeline.lambda$createNewSession$3 (NewSessionPipeline.java:69)
at java.util.stream.ReferencePipeline$3$1.accept (ReferencePipeline.java:193)
at java.util.stream.ReferencePipeline$3$1.accept (ReferencePipeline.java:193)
at java.util.stream.ReferencePipeline$3$1.accept (ReferencePipeline.java:193)
at java.util.stream.DistinctOps$1$2.accept (DistinctOps.java:175)
at java.util.stream.ReferencePipeline$2$1.accept (ReferencePipeline.java:175)
at java.util.stream.ReferencePipeline$3$1.accept (ReferencePipeline.java:193)
at java.util.stream.ReferencePipeline$2$1.accept (ReferencePipeline.java:175)
at java.util.stream.Streams$StreamBuilderImpl.tryAdvance (Streams.java:405)
at java.util.stream.Streams$ConcatSpliterator.tryAdvance (Streams.java:728)
at java.util.stream.ReferencePipeline.forEachWithCancel (ReferencePipeline.java:126)
at java.util.stream.AbstractPipeline.copyIntoWithCancel (AbstractPipeline.java:499)
at java.util.stream.AbstractPipeline.copyInto (AbstractPipeline.java:486)
at java.util.stream.AbstractPipeline.wrapAndCopyInto (AbstractPipeline.java:472)
at java.util.stream.FindOps$FindOp.evaluateSequential (FindOps.java:152)
at java.util.stream.AbstractPipeline.evaluate (AbstractPipeline.java:234)
at java.util.stream.ReferencePipeline.findFirst (ReferencePipeline.java:464)
at org.openqa.selenium.remote.server.NewSessionPipeline.createNewSession (NewSessionPipeline.java:72)
at org.openqa.selenium.remote.server.commandhandler.BeginSession.execute (BeginSession.java:65)
at org.openqa.selenium.remote.server.WebDriverServlet.lambda$handle$0 (WebDriverServlet.java:235)
at java.util.concurrent.Executors$RunnableAdapter.call (Executors.java:511)
at java.util.concurrent.FutureTask.run (FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker (ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run (ThreadPoolExecutor.java:624)
at java.lang.Thread.run (Thread.java:748)
HOOK-ERROR in after_scenario: AttributeError: 'Context' object has no attribute 'driver'
Selenium server log:
10:41:04.537 INFO [ActiveSessionFactory.lambda$apply$11] - Matched factory org.openqa.selenium.grid.session.remote.ServicedSession$Factory (provider: org.openqa.selenium.chrome.ChromeDriverService)
Starting ChromeDriver 76.0.3809.88 (e67b7e2f345cbedc6a24e0074a1a528c724f5915-refs/branch-heads/3809@{#968}) on port 1651
Only local connections are allowed.
Please protect ports used by ChromeDriver and related test frameworks to prevent access by malicious code.
10:51:39.855 INFO [ActiveSessionFactory.apply] - Capabilities are: {
"browserName": "chrome",
"goog:chromeOptions": {
"extensions": [
],
"binary": "\u002fhome\u002f***\u002fopt\u002fPiskel-0.14.0-64bits\u002fpiskel",
"args": [
"--no-sandbox",
"--headless",
"--disable-dev-shm-usage"
]
},
"version": latest
}
=> So, I assume, the webdriver object was never instantiated in a correct way(!?), although the app was opened, hmm...
Env: started the selenium server as follows:
java -Dwebdriver.chrome.driver="driver/linux64/chromedriver"-jar selenium-server-standalone-3.141.59.jar
Source code:
import yaml
from selenium import webdriver
def before_all(context):
try:
with open('./config.yml', 'r') as ymlfile:
config = yaml.load(ymlfile, Loader=yaml.FullLoader)
except:
raise
selenium_config = config['selenium']
context.command_executor = selenium_config['selenium_server'] #http://127.0.0.1:4444/wd/hub
context.driver_caps = {
'browserName': selenium_config['browser'], #chrome
'version': selenium_config['version']
}
context.chrome_options = webdriver.ChromeOptions()
context.chrome_options.binary_location = '/home/***/opt/Piskel-0.14.0-64bits/piskel'
context.chrome_options.add_argument('--no-sandbox')
context.chrome_options.add_argument('--headless') #seems to be useless here
context.chrome_options.add_argument('--disable-dev-shm-usage') #to prevent the message: "unknown error: DevToolsActivePort file doesn't exist" => but it's still there..
def before_scenario(context, scenario):
context.driver = webdriver.Remote(context.command_executor, context.driver_caps, options=context.chrome_options)
# the following sadly also doesn't works ...
#context.driver = webdriver.Chrome("/home/***/driver/linux64/chromedriver", options=context.chrome_options)
context.driver.implicitly_wait(5)
def after_scenario(context, scenario):
context.driver.quit()
def before_feature(context, feature):
pass
def after_feature(context, feature):
pass
So, I hope someone out there have more experience with Selenium + Electron and can give me a hint on how to get this running?
/edit: Tried the same with "Electron API Demos" from here: https://github.com/electron/electron-api-demos/releases => got same errors
Another try was on MacOS Mojave, but got another error (same with chromedriver and chromedriver-electron):
WebDriverException: Message: unknown error: Failed to create a Chrome process.