electron-userland / spectron Goto Github PK
View Code? Open in Web Editor NEWDEPRECATED: ๐ Test Electron apps using ChromeDriver
Home Page: http://electronjs.org/spectron
License: MIT License
DEPRECATED: ๐ Test Electron apps using ChromeDriver
Home Page: http://electronjs.org/spectron
License: MIT License
FYI to others that might hit on this issue, when note integration is set to false, like this:
app.on('ready', function () {
mainWindow = new BrowserWindow({
show : false,
x : 1200,
y : -1000,
width : 500,
height : 400,
webPreferences: {
nodeIntegration: false }
})
the app.browserWindow
will not be available
I'm sure there is a good reason for that , but it caught me off guard and I spent a couple hours trying to figure out why my tests were failing and the browserWindow wasn't set
This is a tracking issue for the page I've started at https://github.com/electron/spectron/wiki/Set-up-development-environment/
Since Spectron is a framework to help with testing, then it would make sense to show a test on its main page :)
Namely at http://electron.atom.io/spectron/ where the example shown is:
Since we already have one on the README.md that would be a good one to use
If you are ok with this idea, I'm happy to send a PR (if you can point me to the code that is used at http://electron.atom.io/spectron/ )
Note: I usually tell devs to resist the temptation to experiment with APIs using simple apps. It is much better to write tests (which leave behind the learning path). For example see https://gist.github.com/DinisCruz/060b427139bc2dd747a214d77dd1f970 which shows the tests I did when understanding @wallabyjs Electron support
Migrate away from deprecated APIs.
The saveScreenshot throw this error
RuntimeError: unknown error: cannot get automation extension from unknown error: page could not be found: chrome-extension://aapnijgdinlhnhlmodcfapnahmbfebeb/_generated_background_page.html
Spectron v.3.2.4
Electron v.1.2.5
So I'm trying to get Spectron running headlessly inside a docker container using xvfb and it doesn't start Electron no matter what I try to do.
This is my docker file
FROM node:6.3
RUN apt-get update
RUN apt-get install g++-multilib lib32z1 lib32ncurses5 -y
RUN apt-get install rpm fakeroot dpkg libdbus-1-dev libx11-dev -y
RUN apt-get install libavahi-compat-libdnssd-dev g++ -y
RUN apt-get install gcc-4.8-multilib g++-4.8-multilib -y
RUN apt-get install libgtk2.0-0 libgtk2.0-dev xvfb -y
RUN apt-get install libxtst6 -y
WORKDIR /app
COPY package.json /app
RUN npm install
RUN apt-get install libxss1 libnss3 libasound2 libgconf-2-4 -y
RUN export ELECTRON_ENABLE_STACK_DUMPING=true
RUN export ELECTRON_ENABLE_LOGGING=true
ADD vendor/docker-entrypoint.sh /entrypoint.sh
RUN chmod 777 /entrypoint.sh
ENTRYPOINT ["/bin/sh", "/entrypoint.sh"]
COPY . /app
And this is my entrypoint.sh
#!/bin/bash
echo "Starting Xvfb"
Xvfb :99 -ac &
sleep 2
export DISPLAY=:99
echo "Executing command $@"
exec "$@"
This exact config works for electron-mocha
which also launches electron processes so I can't tell why Electron isn't starting in this container. If I launch the container interactively I can launch the electron
process and get logs indicating it is running successfully. Is there some dependency I am missing for the chromedriver or something?
Hi. I would like to know what is suppose to remplace this part below for windows and linux;
var app = new Application({ path: '/Applications/MyApp.app/Contents/MacOS/MyApp' })
Is it possible to test nodeIntegration=false windows?
Now I get RuntimeError: unknown error: process is not defined
I'm trying to remote require a module from renderer process, the module itself is from the main process.
However it seems app.electron.remote.require('./main_proc_module') returns a promise that resolves to an empty object.
Can I use remote require with spectron?
How can you get the userData path that's available in electron via
app.getPath('userData')
It seems that spectron does not handle page objects implicitly, so implementing like the example below will result in a browser is defined error.
Docs:
http://webdriver.io/guide/testrunner/pageobjects.html
Example from webdriver io:
https://github.com/webdriverio/webdriverio/tree/master/examples/pageobject
I'm trying to use spectron with mocha. In my beforeEach, I have:
this.app = new Application({path: "bin/package/pluginContainer.html"});
return this.appstart();
This times out after 2000ms. What am I doing wrong? Am I passing the wrong path to Application? I didn't see a description anywhere of what that path is supposed to point to.
Thanks,
-Josh
Since that makes a massive difference on coding these tests
Love the framework! ๐
Is there any way currently to test menu item functionality through spectron? I could test the code itself but that doesn't take into account menu item states like enabled
and visible
.
If not, is there a suggested strategy for testing menu items?
Thanks!
Hi,
I am trying to get a basic test working as per the documentation. I've copied/pasted from the README and adjusted my path to point to the Electron executable but I get a test failure. Here's my test code:
/**
* Created by Clifton Craig on 4/30/16.
*/
describe('Initial spec', function () {
it('Should be easy to test.');
});
var Application = require('spectron').Application;
var assert = require('assert');
describe('application launch', function () {
this.timeout(10000);
beforeEach(function () {
this.app = new Application({
path: '/Applications/Electron.app/Contents/MacOS/Electron'
});
return this.app.start()
});
afterEach(function () {
if (this.app && this.app.isRunning()) {
return this.app.stop()
}
});
it('shows an initial window', function () {
return this.app.client.getWindowCount().then(function (count) {
assert.equal(count, 1)
})
})
});
And here's the output:
SFO1212474815A:nightmare 212474815$ npm test
> [email protected] test /Users/212474815/dev/nightmare
> mocha
Initial spec
- Should be easy to test.
application launch
1) "before each" hook for "shows an initial window"
0 passing (5s)
1 pending
1 failing
1) application launch "before each" hook for "shows an initial window":
Error: ChromeDriver did not start within 5000ms
at Error (native)
at node_modules/spectron/lib/chrome-driver.js:58:25
at Request._callback (node_modules/spectron/lib/chrome-driver.js:116:45)
at Request.self.callback (node_modules/request/request.js:200:22)
at Request.<anonymous> (node_modules/request/request.js:1067:10)
at IncomingMessage.<anonymous> (node_modules/request/request.js:988:12)
at endReadableNT (_stream_readable.js:905:12)
npm ERR! Test failed. See above for more details.
Is there something I've missed from the documentation? Do I need to start ChromeDriver separately? I've never used ChromeDrive or WebDriver before. This is my 1st take at automated Electron testing. Thanks for any/all clarification!
Running 'getting started' script from http://electron.atom.io/spectron/
This is the result:
First window is the application as I wanted it to be (but tests don't pass), other windows look like terminals without anything inside. Anyone seen something similar?
I'm using Windows 10 via VM from https://developer.microsoft.com/en-us/microsoft-edge/tools/vms/mac/
When we create our browser window we also initialize a Configuration object which is stored in the global and gotten again via getGlobal
so that we don't have to constantly initialize. In Electron this works out great because we can do global.appConfig = new Config(app)
and then pull it out with getGlobal later and store it for the entire browser to have access to.
However, spectron only returns the values that are initialized upon class creation and none of the getters, setters or other methods that are defined on the class. A basic example:
class Hello {
constructor() {
this.valueOne = "works"
this.valueTwo = "works"
}
get world() {
return "DoesntWork"
}
}
global.appConfig = new Hello()
import { Application } from "spectron"
import { assert } from "chai"
describe("hello.js", function() {
before(function() {
this.app = new Application({
path: "./node_modules/.bin/electron",
chromeDriverLogPath: "./chrome.driver.log",
args: ["./app/entry.js"]
})
return this.app.start(
//
)
})
after(function() {
if (this.app && this.app.isRunning()) {
this.app.stop(
//
)
}
})
describe("#world", function() {
it("should be a function", async function() {
let config = await this.app.electron.remote.getGlobal("appConfig")
assert.isFunction(config.world)
})
})
})
This ultimately fails because world is not even defined for some reason when getGlobal
gets it, however... valueOne
and valueTwo
are there and ready to be tested/used.
Ubuntu 14.04
Node.js 6.0.0
spectron 3.2.3
electron-prebuilt 1.2.2
Test file:
// test.js
var Application = require('spectron').Application;
const app = new Application({
path: __dirname + '/app.js',
chromeDriverLogPath: __dirname + '/chrome-driver.log'
});
app.start()
.then(function() {
console.log('started');
})
.catch((err) => {
console.log(err);
});
And binary I am passing to application as path
, this is a JS file with "executable" permissions:
// app.js
var electron = require('electron');
electron.app.on('ready', function() {
var window = new electron.BrowserWindow({
width: 800,
height: 600
});
window.loadURL('https://github.com');
});
When I run $ node test.js
it just hangs, no any output in terminal.
After adding chromeDriverLogPath
I've noticed that it infinitely tries to connect to DevTools, but fails. Here is the contents of chrome-driver.log
:
// chrome-driver.log
[0.205][INFO]: COMMAND InitSession {
"desiredCapabilities": {
"browserName": "electron",
"chromeOptions": {
"args": [ "spectron-path=/var/www/github/hanshot/test/int-spectron/app.js" ],
"binary": "/var/www/github/hanshot/node_modules/spectron/lib/launcher.js"
},
"handlesAlerts": true,
"javascriptEnabled": true,
"locationContextEnabled": true,
"loggingPrefs": {
"browser": "ALL",
"driver": "ALL"
},
"requestOrigins": {
"name": "webdriverio",
"url": "http://webdriver.io",
"version": "4.0.9"
},
"rotatable": true
}
}
[0.205][INFO]: Populating Preferences file: {
"alternate_error_pages": {
"enabled": false
},
"autofill": {
"enabled": false
},
"browser": {
"check_default_browser": false
},
"distribution": {
"import_bookmarks": false,
"import_history": false,
"import_search_engine": false,
"make_chrome_default_for_user": false,
"show_welcome_page": false,
"skip_first_run_ui": true
},
"dns_prefetching": {
"enabled": false
},
"profile": {
"content_settings": {
"pattern_pairs": {
"https://*,*": {
"media-stream": {
"audio": "Default",
"video": "Default"
}
}
}
},
"default_content_setting_values": {
"geolocation": 1
},
"default_content_settings": {
"geolocation": 1,
"mouselock": 1,
"notifications": 1,
"popups": 1,
"ppapi-broker": 1
},
"password_manager_enabled": false
},
"safebrowsing": {
"enabled": false
},
"search": {
"suggest_enabled": false
},
"translate": {
"enabled": false
}
}
[0.205][INFO]: Populating Local State file: {
"background_mode": {
"enabled": false
},
"ssl": {
"rev_checking": {
"enabled": false
}
}
}
[0.206][INFO]: Launching chrome: /var/www/github/hanshot/node_modules/spectron/lib/launcher.js
--disable-background-networking --disable-client-side-phishing-detection
--disable-component-update --disable-default-apps --disable-hang-monitor
--disable-popup-blocking --disable-prompt-on-repost --disable-sync --disable-web-resources
--enable-logging --ignore-certificate-errors
--load-extension=/tmp/.org.chromium.Chromium.mdUELY/internal --log-level=0
--metrics-recording-only --no-first-run --password-store=basic
--remote-debugging-port=12902 --safebrowsing-disable-auto-update
--safebrowsing-disable-download-protection
--spectron-path=/var/www/github/hanshot/test/int-spectron/app.js --test-type=webdriver
--use-mock-keychain --user-data-dir=/tmp/.org.chromium.Chromium.KjuOCY data:,
[0.206][DEBUG]: DevTools request: http://localhost:12902/json/version
[0.246][DEBUG]: DevTools request failed
[0.296][DEBUG]: DevTools request: http://localhost:12902/json/version
[0.297][DEBUG]: DevTools request failed
[0.347][DEBUG]: DevTools request: http://localhost:12902/json/version
[0.347][DEBUG]: DevTools request failed
[0.397][DEBUG]: DevTools request: http://localhost:12902/json/version
[0.397][DEBUG]: DevTools request failed
[0.448][DEBUG]: DevTools request: http://localhost:12902/json/version
[0.448][DEBUG]: DevTools request failed
[0.498][DEBUG]: DevTools request: http://localhost:12902/json/version
[0.498][DEBUG]: DevTools request failed
[0.549][DEBUG]: DevTools request: http://localhost:12902/json/version
[0.549][DEBUG]: DevTools request failed
[0.599][DEBUG]: DevTools request: http://localhost:12902/json/version
[0.600][DEBUG]: DevTools request failed
[0.650][DEBUG]: DevTools request: http://localhost:12902/json/version
[0.650][DEBUG]: DevTools request failed
[0.700][DEBUG]: DevTools request: http://localhost:12902/json/version
[0.701][DEBUG]: DevTools request failed
[0.751][DEBUG]: DevTools request: http://localhost:12902/json/version
[0.751][DEBUG]: DevTools request failed
[0.801][DEBUG]: DevTools request: http://localhost:12902/json/version
[0.802][DEBUG]: DevTools request failed
[0.852][DEBUG]: DevTools request: http://localhost:12902/json/version
[0.852][DEBUG]: DevTools request failed
[0.903][DEBUG]: DevTools request: http://localhost:12902/json/version
[0.903][DEBUG]: DevTools request failed
[0.953][DEBUG]: DevTools request: http://localhost:12902/json/version
[0.953][DEBUG]: DevTools request failed
[1.003][DEBUG]: DevTools request: http://localhost:12902/json/version
[1.004][DEBUG]: DevTools request failed
[1.054][DEBUG]: DevTools request: http://localhost:12902/json/version
[1.054][DEBUG]: DevTools request failed
[1.104][DEBUG]: DevTools request: http://localhost:12902/json/version
[1.104][DEBUG]: DevTools request failed
[1.155][DEBUG]: DevTools request: http://localhost:12902/json/version
[1.155][DEBUG]: DevTools request failed
[1.205][DEBUG]: DevTools request: http://localhost:12902/json/version
[1.205][DEBUG]: DevTools request failed
[1.256][DEBUG]: DevTools request: http://localhost:12902/json/version
[1.256][DEBUG]: DevTools request failed
[1.306][DEBUG]: DevTools request: http://localhost:12902/json/version
[1.307][DEBUG]: DevTools request failed
...
Even though there are some bugs with same message in the web, I was not able to find any information what might cause this issue. I can only see that Chrome instance is started with flag --remote-debugging-port=12902
, but I never set it.
Is it because of chrome-driver?
Seems like it was updated to 2.22 recently https://sites.google.com/a/chromium.org/chromedriver/ to support Chrome 49-52 and as I can see latest electron uses Chrome 51 and Spectron uses chrome-driver 2.21.
Thanks!
It would be good track it and know where the gaps are (good place to start submitting PRs)
What is a good way to run multiple tests using the same electron window?
The test examples I have seen, tend to show the use of beforeEach and afterEach to start and stop the electron instance, but this has a 2 sec penalty per test
For example note how in the tests bellow the 'check Html' and 'check title' tool 2sec each
Ideally I would like to keep an instance of Electron opened which I can then use on demand to load pages in the browser window (or to create new ones).
And yes I know that there are cases where we want to have a pristine browser session, but in most browser automation cases that is not really needed
I've tested the code with ava and It worked well. I think, It would be helpful that add sample code for ava to readme.
Having created an electron application with a main.js and an index.html,
And it runs with a GUI on the command:
node_modules/.bin/electron .
or
npm start
Using the Spectron "Get Started" example, saving "a sample test" as "testApp.js",
What should be the value of:
var app = new Application({ path: ' ??? ' })
And what is the command to invoke this code, which runs the GUI app and performs the test?
Clearly it is not "node testApp.js", or I have not configured things correctly.
Thanks!
Hi, I'm considering to take a screenshot of app when test failed. I found BrowserWindow
's capturePage
method but it doesn't work from Spectron as below.
$ npm install spectron electron-prebuilt
$ node below-code.js
'use strict';
const Application = require('spectron').Application;
const electron = require('electron-prebuilt');
const app = new Application({path: electron});
app.start();
// Wait for app starting
setTimeout(() => {
console.log('start');
app.browserWindow
.capturePage(img => {
console.log(img);
const fs = require('fs');
fs.writeFile('screenshot.png', img.toPng());
})
.then(result => {
console.log('RESULT:', result);
app.stop();
});
}, 3000);
This is an issue and a request for help.
My app mostly relies on webviews for partitioning out 'plugins' that hold most of the app's functionality. I can't do anything with Webdriver to test these plugins besides sending and listening through ipc. Even when adding an ipc listener on the renderer through client.execute
, I can't retrieve the value obtained by said listener. See below, especially the 6th to last line.
// Libraries required for testing
const Application = require('spectron').Application;
const Chai = require('chai');
const ChaiAsPromised = require('chai-as-promised');
const Path = require('path');
const Crypto = require('crypto');
// Chai's should syntax is executed to edit Object to have Object.should
var should = Chai.should();
// Chai's should syntax is extended to deal well with Promises
Chai.use(ChaiAsPromised);
describe('renderer process', function() {
var app;
var client;
// Starts a new session and assigns spectron's Application instance to a
// variable, app, available to all tests
before('start electron', function() {
app = new Application({
path: Path.join(__dirname, '../node_modules/.bin/electron'),
args: [Path.join(__dirname, '..')],
});
return app.start();
});
// Extends ChaiAsPromised's syntax with spectron's electron-specific
// functions and assigns spectron's WebDriverIO properties to a variable,
// client, available to all tests
before('transfer spectron methods', function() {
client = app.client;
ChaiAsPromised.transferPromiseness = client.transferPromiseness;
});
// Close session after each test-suite
after('stop electron', function() {
if (app && app.isRunning()) {
return app.stop();
}
});
// Test basic startup properties
describe('plugin', function() {
// Helper to have the UI add an IPC listener
function addIPCListener(channel, response) {
client.execute(function(c, r) {
IPCRenderer.on(channel, response);
}, channel, response);
}
// Helper to have a plugin add an IPC listener
function addPluginIPCListener(name, channel, response) {
client.execute(function(n, c, r) {
Plugins[n].execute('IPC.on(' + c + ', ' + r.toString());
}, name, channel, response);
}
// Helper to send an IPC message to a plugin
function sendPluginIPC(name, channel, args) {
args.unshift(channel);
client.execute(function(n, a) {
Plugins[n].sendToView.apply(this, a);
}, name, args);
}
// Helper to get a variable's value from the plugin via IPC
function getPluginVariable(name, varName) {
// Generate one-off IPC channel to transfer variable across on both ways
var channel = Crypto.randomBytes(20).toString('hex');
addPluginIPCListener(name, channel, function() {
IPCRenderer.sendToHost(channel, varName);
});
addIPCListener(channel, function(event, varValue) {
// Is there anything I can do here to send a variable or value back to the Webdriver?
});
sendPluginIPC(name, channel, varName);
}
});
});
Sorry this is a long post, but I think the dilemma makes itself clear. Any ideas?
For example:
This is what I started doing with https://github.com/o2platform/chrome-js which was originally based on NWR, but since Electron really become stable, I have been trying to use it
@kevinsawicki thanks for working on this. It's awesome to directly test with electron app, Adding below lines to electron default app, is sufficient to reproduce this, thought of adding this as issue, in turn might help someone save time.
Ex :
var app = require('app');
app.commandLine.appendSwitch('remote-debugging-port', '9222');
If the electron app has a beforeunload that cancel the app quit like this
// index.html
window.onbeforeunload = function(e) {
console.log('app quit canceled')
return false
};
Then try to close the spectron app
// test.js
if (this.app && this.app.isRunning()) {
return this.app.stop().then(function() {
console.log('stopped')
})
}
The output is "stopped" even if app is still running.
The expected behaviour is the this.app.stop() promise rejects
Electron 1.1.1
Spectron 3.1.1
Hey,
I am trying to check the title of my second window. Is this a bug, or am I doing something wrong?
let handles = await app.client.windowHandles();
console.log(handles);
/*
{ sessionId: '0d66b5bac77357c36ea41fd298e55854',
status: 0,
value:
[ 'CDwindow-97CD6BD5-C47A-45C1-9A66-7D0FF3B2F9DF',
'CDwindow-946E9CE7-9A1C-458A-9DE2-00A975ACC5BD' ] }
*/
await app.client.windowByIndex(1);
console.log(await app.client.browserWindow.getTitle());
BTW windowHandles
is missing in the readme. Also I saw on stackoverflow that somebody was doing windowByIndex(handles.values[1])
but this also fails for me.
What is also weird is that my second window actually has focus, but app.client.browserWindow.getTitle()
will get me the title of the first window. How can I make app.client.browserWindow
to point at currently focused window?
chaiAsPromised doesn't properly handle rejections, and constantly reports true for some spectron
methods when using some Promised methods. For example:
it("should be true", function() {
let val = this.app.electron.remote.getGlobal("appConfig").then(v => { return v.val })
assert.eventually.equal(
val, true
)
})
Always returns true for us, and never actually causes an assertion failure because there was a rejection with the object having an error. We could catch it, but then what is the point of chaiAsPromised at that point?
I propose the documentation also recommend a better way to deal with promises if they are using ES7.
it("should be true", async function() {
let config = await this.app.electron.remote.getGlobal("appConfig")
assert.equal(
config.val, true
)
})
If this is acceptable, I'm happy to send a pull request.
Hello,
I'm currently trying to make use of spectron for my angular2 app. My index.html contains the following lines:
window.electronRequire = require;
delete window.require;
delete window.exports;
delete window.module;
This is needed because some of the code I load otherwise hook these symbols and that messes with the code loading. However, api.js seems to fail because the require symbol is deleted. Manually patching up api.js to use electronRequire makes things work fine, but this is obviously less than ideal
Any suggestions for dealing with this?
Is it possible to set things up, so that electron process console output is directed to console of a process that launches spectron?
Sometimes it is useful for a quick check.
I am opening dialog in my app like this:
const path = dialog.showOpenDialog(remote.getCurrentWindow(), {
title: i18n.t("Where do you want to save it?"),
properties: ['openDirectory', 'createDirectory']
});
And I cannot find way to select directory in tests. I tried using webdriverio's keys
with no luck. I thought that maybe electron creates second window and that's why I can't interact with it but by using client.getWindowCount()
it founds only 1 window. Any ideas?
Hello
Is it possible to set chromeOptions.debuggerAddress ? We need to launch our app outside of ChromeDriver so we can set custom Chromium command options.
Thanks for the great tool
I can't seem to access any logs from neither the browser process nor the render processes. Any ideas on how to do this?
Selenium has a /session/:sessionId/log
and /session/:sessionId/log/types
endpoint that I'm successfully able to access via the webdriver
client.log()
and client.logTypes()
APIs. logTypes
resolves to an array with ['browser', 'driver']
.
Unfortunately, the value of the logs coming out of the browser
type is always empty. I can see that the app boots, and I can open the inspector console and see logs and enter more console.log
commands, but nothing ever comes back when you request the logs via client.log
.
this.app.start().then(()=> {
this.app.client.log("browser").then(({value}) => {
console.log(value) // Always an empty []
})
})
I've also tried putting that log polling function on an interval thinking that it wouldn't return anything until the app fully booted. It never returns any data.
On the flip side, polling app.client.log("driver")
returns all of the Selenium driver log data properly.
I've been playing around using spectron (-v 0.34.0) with tape (-v 4.2.2) and am running into difficulty using the getWindowWidth and getWindowHeight commands.
Here's the test I'm running:
this.app.client.getWindowHeight().then(function(height) {
t.equal(height, 600)
})
It appears that the getWindowDimensions execution is passing a null response.value to getResponseValue.
{ sessionId: 'abe9c8387e2d12ea86fb59dfb4faebe7',
status: 0,
value: null }
An equivalent test using mocha and assert run without problems.
Note, using the getWindowDimensions command runs fine as such:
this.app.client.getWindowDimensions().then(function(dimensions) {
t.equal(dimensions.height, 600)
t.equal(dimensions.width, 900)
})
Any ideas?
I have an app whose startup sequence is as follows:
I wait for 10 seconds in my tests before issuing commands via the APIs. However they don't work because client.execute()
doesn't work - and I think this is because the webdriver client
API gets initialized agains the splash window since that shows up first - am I right?
How can I make it so that I can issue commands agains the main app window?
Might need to iron out a few things regarding the wrapper script
I'm trying to run the basic demo and am receiving this error
I tracked it to here where the self.client.init().
value is not defined (in https://github.com/electron/spectron/blob/db2d66733dbd79c3d8aeed5427e591ac579a89fc/lib/application.js#L153)
It is caused by the fact that the object returned from https://github.com/electron/spectron/blob/db2d66733dbd79c3d8aeed5427e591ac579a89fc/lib/application.js#L141 does not have an ```.init() function
Here is the code (which is based on the main example):
electron_Prebuild = require('electron-prebuilt')
electronPath = '/Users/diniscruz/GitHub_REPOS/BSIMM-Graphs/node_modules/electron-prebuilt/dist/Electron.app/Contents/MacOS/Electron'
appPath = '/Users/diniscruz/GitHub_REPOS/BSIMM-Graphs/test-spectron/electron-apps/web-view'
var Application = require('spectron').Application
var assert = require('assert')
describe('application launch 2', function () {
this.timeout(10000)
beforeEach(function () {
this.app = new Application({
path: electronPath,
args: [appPath]
})
return this.app.start()
})
afterEach(function () {
if (this.app && this.app.isRunning()) {
return this.app.stop()
}
})
it('shows an initial window', function () {
return this.app.client.getWindowCount().then(function (count) {
assert.equal(count, 1)
})
})
})
In the following use case (waiting for a signin button, clicking it and then attempting to enter a password. The renderer process of the WebView crashes with this sample code. The WebView's devtools become completely empty and all other client
methods fail.
This code fails and the click
event is not fired.
app.client
.waitUntilWindowLoaded()
.windowByIndex(1)
.waitForVisible('[data-action=signin]').should.eventually.be.true
.leftClick('[data-action=signin]').should.eventually.be.ok
.waitForVisible('#Passwd').should.eventually.be.true;
However, this code works and the click
event is fired.
app.client
.waitUntilWindowLoaded()
.windowByIndex(1)
.waitForVisible('[data-action=signin]').should.eventually.be.true
.leftClick('[data-action=signin]').should.eventually.be.ok;
With my understanding of how this is supposed to work it makes no sense that adding a WebDriver call to the end can break a call that works before it. Do you have any idea what is going on here?
Throw a nicer error when accessing a helper that is dependent on nodeIntegration
being enabled.
Please consider the possibility to provide typings so we can use Typescript with our tests.
I am adapting an existing test suite (using mocha and chai/chai as promised) using WDIO Testrunner to use an electron version of the app the tests were originally written for. The example in the documentation of a test with chai as promised does not use a test runner file, just a standalone test, nor can I find an example of WDIO Testrunner being used elsewhere in the documentation. Is it possible to use WDIO Testrunner in conjunction with Spectron? When I try to configure the testrunner file to use the electron app instead of chrome (via chromeOptions: {binary: 'path'}), the app launches, but all tests timeout and fail.
The documentation indicates that Spectron exposes the client property of an Application instance. The current set of tests I have use the browser global object. How are these two objects related, and is there some straight-forward way of converting these objects? There also does not seem to be a clear cut way of exposing the client property from the test runner file itself, is this correct?
From a maintainability perspective, it would be really beneficial if I could simply write a different Testrunner file specific to the electron app that utilises the same underlying test files as the web app. Is this possible?
Here's my Testrunner file and an example of the tests I am trying to run:
exports.config = {
host: 'localhost',
port: '4444',
path: '/wd/hub',
specs: [
'./ui/*.js'
],
maxInstances: 1,
capabilities: [{
browserName: 'chrome',
chromeOptions: {
// binary: 'path/to/electron/app'
}
}],
logLevel: 'silent',
sync: false,
coloredLogs: true,
screenshotPath: './errorShots/',
baseUrl: 'http://localhost:3000',
waitforTimeout: 19500,
framework: 'mocha',
mochaOpts: {
timeout: 20000
},
reporters: ['dot'],
reporterOptions: {
outputDir: './logs/'
},
before: function() {
var chai = require('../service/node_modules/chai/chai');
var chaiAsPromised = require('../service/node_modules/chai-as-promised');
expect = chai.expect;
chai.Should();
chai.use(chaiAsPromised);
chaiAsPromised.transferPromiseness = browser.transferPromiseness;
//File specifying ui actions -- defines custom commands
require('./framework/app_extensions.js');
}
};
describe("Menu tests", function() {
console.log('\nMenu Tests:')
// check Menu visibility
describe("Menu visibility", function() {
it("should be visible", function() {
return browser
.openApp() // contained in app_extensions.js
.isVisible('.menu').should.eventually.be.true
.isVisible('#dropdownModelsMenu').should.eventually.be.true;
});
});
// check Model submenu
describe("Models Menu", function(){
var modelsMenuId = "#dropdownModelsMenu";
var modelsSubMenu = ["#open-model", "#import-model", "#save-project", "#export-model", "#delete-project"];
it("should open the submenu", function() {
return browser
.openApp()
.waitForEnabled(modelsMenuId)
.click(modelsMenuId)
.waitForVisible(modelsSubMenu[0])
.isVisible(modelsSubMenu[0]).should.eventually.be.true
.isVisible(modelsSubMenu[1]).should.eventually.be.true
.isVisible(modelsSubMenu[2]).should.eventually.be.true
.isVisible(modelsSubMenu[3]).should.eventually.be.true
.isVisible(modelsSubMenu[4]).should.eventually.be.true;
});
it("should disable submenu options when model not loaded", function() {
return browser
.openApp()
.waitForEnabled(modelsMenuId)
.click(modelsMenuId)
.getAttribute(modelsSubMenu[2], 'class').should.eventually.contain('disabled')
.getAttribute(modelsSubMenu[3], 'class').should.eventually.contain('disabled')
.getAttribute(modelsSubMenu[4], 'class').should.eventually.contain('disabled');
});
});
});
I have been looking into this over the past few days haven't met much with success. Any help would be greatly appreciated. Thanks.
I am trying to find an element on the page with waitUntilTextExists
, but it cannot be found. Not sure if this is the right place, but I've decided to open up an issue in case somebody spots anything wrong with what I am doing:
return myApp.client.waitForVisible('.btn-add').then(function(text) {
console.log(text);
});
Code here and this is the element I am trying to find: .btn-add
.
I have tried different ways, including one similar to the example here, but none of them worked. I've captured the full error with catch: An element could not be located on the page using the given search parameters.
Perhaps this belongs on the webdriver project?
Hello
I created a PR for verbose logging, but not sure if it needs an issue to go with it. So here it is.
Thanks
Hi @kevinsawicki,
I gave a try to the sample here. It successfully run the appp, but than it failed as follows:
application launch
1) "before each" hook for "shows an initial window"
0 passing (10s)
1 failing
1) application launch "before each" hook for "shows an initial window":
Error: timeout of 10000ms exceeded. Ensure the done() callback is being called in this test.
My repo: https://github.com/vchimev/spectron-sample
Any help would be appreciated,
@vchimev
I tried to start an application which included module 'babel-polyfill'. Sometimes, it can not load module 'babel-polyfill'. It happened about 4/5 times when i try to run my test script.
Please take a look at my script: test script
I would like to unit testing my electron into headless (on remote server). There's a sample app somewhere to see how to write a basic test from a sample application ? Spectron looks good for that but I cant figure how to apply this to a project.
I'm following the examples in the README on OS X, but I get the following popup with the following message whenever it runs the beforeEach to start the app again:
The last time you opened APP_NAME, it unexpectedly quit while reopening windows. Do you want to try to reopen its windows again?
Anyone else running into this issue?
I find that when writing these type of UI tests, it makes a massive difference for the dev environment to hide the image so that it doesn't show in the screen and interrupt the dev's workflow (since the eyes are drawn to the newly created window).
There is also the .showInactive()
which can be used to show the window but not give it focus. This means that we can continue to type the test as it executes (which is what happens when WallabyJS is used, see #35)
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.