nwjs / nw.js

Call all Node.js modules directly from DOM/WebWorker and enable a new way of writing applications with all Web technologies.
https://nwjs.io
MIT License
40.34k stars 3.88k forks source link

Using Nightwatch with NWjs #4285

Closed juicetin closed 8 years ago

juicetin commented 8 years ago

Hi,

Apologies if this isn't actually an 'issue' in the technical/software dev sense.

I've been trying a number of things to try and use Nightwatch js with NWjs for UI testing, but there seem to be some major obstacles that I haven't been able to over come after numerous hours.

The most prominent one is that fs.readFileSync is undefined when opened in a browser - but considering that I browserify my files, that function call is needed every time a node_module-type 'require' appeared anywhere in my code pre-browserification.

Furthermore, I use fs-promise in other places in my code so that I can read a config file that is local to the repository.

Note that this is because the selenium server runs chrome (or Firefox) - if there was some way for it to run the node-webkit 'browser', I imagine the problem would at least partially be solved.

I may have missed something (also looked through the NWjs tests themselves - doesn't seem relevant to me in this case though) - but is there a recommended way for UI testing where we can select elements in an app by CSS classes/ids/etc.?

Thanks in advance.

juicetin commented 8 years ago

To provide a suggestion to my own question - seeing as Chrome (the browser I was running Nightwatchjs in) seems to have full support for the File System API, something to explore would be to detect whether the app is being run in NWjs or, say, Chrome - and adjust the fs 'library' accordingly so that my app can read files from within NWjs/browser respectively.

I'll post back here if I have any luck with it.

Note: this workaround is Chrome-specific and may not even have a future within Chrome, as it's a dead spec and not being considered by other browsers/dumped by the w3c. Source: http://lists.w3.org/Archives/Public/public-webapps/2014AprJun/0010.html

ghostoy commented 8 years ago

Just to clarify, you are asking for UI testing tools for NW, right?

juicetin commented 8 years ago

@ghostoy yes, that was what I was requesting (more on the basis that I personally wasn't able to find an existing tool and mould it to be compatible with NWjs - at the same time I think it is likely I may have missed something and this may actually be possible - I opened an issue anyway in case this was the case and someone could point out the missing link)

ghostoy commented 8 years ago

NW provides a chromedriver. You can use selenium to automate UI testing.

juicetin commented 8 years ago

Thanks for the tip. Unfortunately after much tinkering I can't get selenium (amongst other things?) to play nice. The instructions here wouldn't work for me: https://github.com/nwjs/nw.js/wiki/chromedriver

When I try running x.init({ browserName: "chrome" }), I get the error below. I've also tried it programatically in Python with errors there as well. Would you happen to know if the instructions are 'missing' any steps or taking for granted certain aspects of the environment? I'm running 64-bit Arch Linux. Any help would be greatly appreciated, I haven't been able to make any progress after several hours.

Errors from Selenium when doing it via the wd REPL:

$ java -jar selenium-server-standalone-2.49.1.jar -Dwebdriver.chrome.driver=/home/justinting/programming/sourcetree_nw_unofficial/bin/chromedriver2_server
09:00:58.783 INFO - Launching a standalone Selenium Server
Setting system property webdriver.chrome.driver to /home/justinting/programming/sourcetree_nw_unofficial/bin/chromedriver2_server
09:00:58.818 INFO - Java: Oracle Corporation 24.95-b01
09:00:58.818 INFO - OS: Linux 4.3.3-3-ARCH amd64
09:00:58.829 INFO - v2.49.1, with Core v2.49.1. Built from revision 7203e46
09:00:58.895 INFO - Driver provider org.openqa.selenium.ie.InternetExplorerDriver registration is skipped:
registration capabilities Capabilities [{platform=WINDOWS, ensureCleanSession=true, browserName=internet explorer, version=}] does not match the current platform LINUX
09:00:58.895 INFO - Driver provider org.openqa.selenium.edge.EdgeDriver registration is skipped:
registration capabilities Capabilities [{platform=WINDOWS, browserName=MicrosoftEdge, version=}] does not match the current platform LINUX
09:00:58.896 INFO - Driver class not found: com.opera.core.systems.OperaDriver
09:00:58.896 INFO - Driver provider com.opera.core.systems.OperaDriver is not registered
09:00:58.897 INFO - Driver provider org.openqa.selenium.safari.SafariDriver registration is skipped:
registration capabilities Capabilities [{platform=MAC, browserName=safari, version=}] does not match the current platform LINUX
09:00:58.959 INFO - RemoteWebDriver instances should connect to: http://127.0.0.1:4444/wd/hub
09:00:58.959 INFO - Selenium Server is up and running
09:02:17.712 INFO - Executing: [new session: Capabilities [{platform=ANY, javascriptEnabled=true, browserName=chrome, version=}]])
09:02:17.723 INFO - Creating a new session for Capabilities [{platform=ANY, javascriptEnabled=true, browserName=chrome, version=}]
Starting ChromeDriver (v2.2) on port 15398
09:02:27.556 WARN - Exception thrown
java.util.concurrent.ExecutionException: org.openqa.selenium.WebDriverException: java.lang.reflect.InvocationTargetException
Build info: version: '2.49.1', revision: '7203e46', time: '2016-01-21 17:35:35'
System info: host: 'justinting', ip: '192.168.43.170', os.name: 'Linux', os.arch: 'amd64', os.version: '4.3.3-3-ARCH', java.version: '1.7.0_95'
Driver info: driver.version: unknown
        at java.util.concurrent.FutureTask.report(FutureTask.java:122)
        at java.util.concurrent.FutureTask.get(FutureTask.java:188)
        at org.openqa.selenium.remote.server.DefaultSession.execute(DefaultSession.java:183)
        at org.openqa.selenium.remote.server.DefaultSession.<init>(DefaultSession.java:119)
        at org.openqa.selenium.remote.server.DefaultSession.createSession(DefaultSession.java:95)
        at org.openqa.selenium.remote.server.DefaultDriverSessions.newSession(DefaultDriverSessions.java:124)
        at org.openqa.selenium.remote.server.handler.NewSession.handle(NewSession.java:59)
        at org.openqa.selenium.remote.server.handler.NewSession.handle(NewSession.java:1)
        at org.openqa.selenium.remote.server.rest.ResultConfig.handle(ResultConfig.java:111)
        at org.openqa.selenium.remote.server.JsonHttpCommandHandler.handleRequest(JsonHttpCommandHandler.java:79)
        at org.openqa.selenium.remote.server.DriverServlet.handleRequest(DriverServlet.java:202)
        at org.openqa.selenium.remote.server.DriverServlet.doPost(DriverServlet.java:164)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:707)
        at org.openqa.selenium.remote.server.DriverServlet.service(DriverServlet.java:130)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
        at org.openqa.jetty.jetty.servlet.ServletHolder.handle(ServletHolder.java:428)
        at org.openqa.jetty.jetty.servlet.ServletHandler.dispatch(ServletHandler.java:680)
        at org.openqa.jetty.jetty.servlet.ServletHandler.handle(ServletHandler.java:571)
        at org.openqa.jetty.http.HttpContext.handle(HttpContext.java:1526)
        at org.openqa.jetty.http.HttpContext.handle(HttpContext.java:1479)
        at org.openqa.jetty.http.HttpServer.service(HttpServer.java:920)
        at org.openqa.jetty.http.HttpConnection.service(HttpConnection.java:820)
        at org.openqa.jetty.http.HttpConnection.handleNext(HttpConnection.java:986)
      at org.openqa.jetty.http.HttpConnection.handleNext(HttpConnection.java:986)
        at org.openqa.jetty.http.HttpConnection.handle(HttpConnection.java:837)
        at org.openqa.jetty.http.SocketListener.handleConnection(SocketListener.java:243)
        at org.openqa.jetty.util.ThreadedServer.handle(ThreadedServer.java:358)
        at org.openqa.jetty.util.ThreadPool$PoolThread.run(ThreadPool.java:537)
Caused by: org.openqa.selenium.WebDriverException: java.lang.reflect.InvocationTargetException
Build info: version: '2.49.1', revision: '7203e46', time: '2016-01-21 17:35:35'
System info: host: 'justinting', ip: '192.168.43.170', os.name: 'Linux', os.arch: 'amd64', os.version: '4.3.3-3-ARCH', java.version: '1.7.0_95'
Driver info: driver.version: unknown
        at org.openqa.selenium.remote.server.DefaultDriverProvider.callConstructor(DefaultDriverProvider.java:113)
        at org.openqa.selenium.remote.server.DefaultDriverProvider.newInstance(DefaultDriverProvider.java:97)
        at org.openqa.selenium.remote.server.DefaultDriverFactory.newInstance(DefaultDriverFactory.java:60)
        at org.openqa.selenium.remote.server.DefaultSession$BrowserCreator.call(DefaultSession.java:222)
        at org.openqa.selenium.remote.server.DefaultSession$BrowserCreator.call(DefaultSession.java:1)
        at java.util.concurrent.FutureTask.run(FutureTask.java:262)
        at org.openqa.selenium.remote.server.DefaultSession$1.run(DefaultSession.java:176)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
        at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.reflect.InvocationTargetException
        at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
        at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
        at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
        at java.lang.reflect.Constructor.newInstance(Constructor.java:526)
        at org.openqa.selenium.remote.server.DefaultDriverProvider.callConstructor(DefaultDriverProvider.java:103)
        ... 9 more
Caused by: org.openqa.selenium.WebDriverException: unknown error: cannot find Chrome binary
  (Driver info: chromedriver=2.2,platform=Linux 4.3.3-3-ARCH x86_64) (WARNING: The server did not provide any stacktrace information)
Command duration or timeout: 116 milliseconds
Build info: version: '2.49.1', revision: '7203e46', time: '2016-01-21 17:35:35'
System info: host: 'justinting', ip: '192.168.43.170', os.name: 'Linux', os.arch: 'amd64', os.version: '4.3.3-3-ARCH', java.version: '1.7.0_95'
Driver info: org.openqa.selenium.chrome.ChromeDriver
        at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
        at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
        at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
        at java.lang.reflect.Constructor.newInstance(Constructor.java:526)
        at org.openqa.selenium.remote.ErrorHandler.createThrowable(ErrorHandler.java:206)
        at org.openqa.selenium.remote.ErrorHandler.throwIfResponseFailed(ErrorHandler.java:158)
        at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:678)
        at org.openqa.selenium.remote.RemoteWebDriver.startSession(RemoteWebDriver.java:249)
        at org.openqa.selenium.remote.RemoteWebDriver.<init>(RemoteWebDriver.java:131)
        at org.openqa.selenium.remote.RemoteWebDriver.<init>(RemoteWebDriver.java:144)
        at org.openqa.selenium.chrome.ChromeDriver.<init>(ChromeDriver.java:170)
        at org.openqa.selenium.chrome.ChromeDriver.<init>(ChromeDriver.java:138)
        ... 14 more
09:02:27.562 WARN - Exception: unknown error: cannot find Chrome binary
  (Driver info: chromedriver=2.2,platform=Linux 4.3.3-3-ARCH x86_64) (WARNING: The server did not provide any stacktrace information)
Command duration or timeout: 116 milliseconds
Build info: version: '2.49.1', revision: '7203e46', time: '2016-01-21 17:35:35'
System info: host: 'justinting', ip: '192.168.43.170', os.name: 'Linux', os.arch: 'amd64', os.version: '4.3.3-3-ARCH', java.version: '1.7.0_95'
Driver info: org.openqa.selenium.chrome.ChromeDriver

Errors when doing it programatically via Python:

Traceback (most recent call last):
  File "./python.py", line 9, in <module>
    driver = webdriver.Chrome('/home/justinting/programming/sourcetree_nw_unofficial/bin/chromedriver2_server', chrome_options=chrome_options)
  File "/usr/lib/python3.5/site-packages/selenium/webdriver/chrome/webdriver.py", line 67, in __init__
    desired_capabilities=desired_capabilities)
  File "/usr/lib/python3.5/site-packages/selenium/webdriver/remote/webdriver.py", line 87, in __init__
    self.start_session(desired_capabilities, browser_profile)
  File "/usr/lib/python3.5/site-packages/selenium/webdriver/remote/webdriver.py", line 141, in start_session
    'desiredCapabilities': desired_capabilities,
  File "/usr/lib/python3.5/site-packages/selenium/webdriver/remote/webdriver.py", line 201, in execute
    self.error_handler.check_response(response)
  File "/usr/lib/python3.5/site-packages/selenium/webdriver/remote/errorhandler.py", line 188, in check_response
    raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.WebDriverException: Message: 

Exception ignored in: <bound method Service.__del__ of <selenium.webdriver.chrome.service.Service object at 0x7f718bb56438>>
Traceback (most recent call last):
  File "/usr/lib/python3.5/site-packages/selenium/webdriver/common/service.py", line 141, in __del__
    self.stop()
  File "/usr/lib/python3.5/site-packages/selenium/webdriver/common/service.py", line 120, in stop
    self.send_remote_shutdown_command()
  File "/usr/lib/python3.5/site-packages/selenium/webdriver/common/service.py", line 99, in send_remote_shutdown_command
    url_request.urlopen("http://127.0.0.1:%d/shutdown" % self.port)
  File "/usr/lib/python3.5/urllib/request.py", line 162, in urlopen
    return opener.open(url, data, timeout)
  File "/usr/lib/python3.5/urllib/request.py", line 465, in open
    response = self._open(req, data)
  File "/usr/lib/python3.5/urllib/request.py", line 483, in _open
    '_open', req)
  File "/usr/lib/python3.5/urllib/request.py", line 443, in _call_chain
    result = func(*args)
  File "/usr/lib/python3.5/urllib/request.py", line 1268, in http_open
    return self.do_open(http.client.HTTPConnection, req)
  File "/usr/lib/python3.5/urllib/request.py", line 1242, in do_open
    raise URLError(err)
urllib.error.URLError: <urlopen error [Errno 111] Connection refused>
juicetin commented 8 years ago

For anyone who comes across this in future:

From the link in the above post, make sure you follow the step where it tells you to put the chromedriver2_server file in the same location as the nw executable (pretty self explanatory - but I skipped over it).

This is likely going to be in your usr/lib/node_modules/nw folder, at least on Linux - not sure about other OSes.

Thanks for pointing me in the right direction @ghostoy!