I am able to launch the electron app with Spectron but not able to perform any actions on it.
OS: Windows 8.1
Node Version : 10.16.0
Spectron: 3.8.0
var Application = require('spectron').Application;
var chai = require('chai');
var chaiAsPromised = require('chai-as-promised');
const SearchPage = require('./page-objects/search.page');
const assert= require('assert');
describe('Test Suite', function () {
this.timeout(20000);
beforeEach('Start Application', function () {
this.app = new Application({
path: 'path of .exe file located', // Ex: D:\\Foldername\\filename.exe
requireName:'electronRequire',
env: {
NODE_ENV: 'test'
}
});
chai.should();
chai.use(chaiAsPromised);
chaiAsPromised.transferPromiseness = this.app.transferPromiseness;
return this.app.start()
});
afterEach(() => {
if (this.app && this.app.isRunning()) {
return this.app.stop();
}
});
it('Sign In, function () {
return this.app.client.
.pause(20000) //waiting for login window
.setValue(SearchPage.username, 'username').pause(1000)
.setValue(SearchPage.password, 'password').pause(1000)
.click(SearchPage.loginButton);
});
});
Package.json file:
{
"name": "spectron-test-framework",
"version": "1.0.0",
"description": "Test Framework for Electron Desktop Application",
"main": "index.js",
"scripts": {
"test": "mocha --timeout 20000",
},
"author": "Tester",
"license": "ISC",
"devDependencies": {
"webdriverio": "^4.10.2",
"chai": "^4.1.2",
"chai-as-promised": "^7.1.1",
"electron": "^2.0.2",
"mocha": "^5.2.0",
"mochawesome": "^3.0.2",
"spectron": "^3.8.0"
}
}
I am unable to interact the elements and seeing error as
1) Test Suite Sign In: Error: Timeout of 20000ms exceeded. For async tests and hooks, ensure "done()" is called; if returning a Promise, ensure it resolves. (D:\spectron-example\Spec.js)
Even if I am increasing the timeout still seeing this timeout error.
How to fix this issue?
And my Questions are
Can we Start writing automation script without development code base ? because in most of the sample tests I have seen automation script is available in test folder of development code.
I have .exe while launching which I am able to see application being launched but not able to perform actions. Does .exe file needs to be provided to QA for automation with any specific packages and options enabled/disabled.
What are the Ideal Electron, Spectron, Nodejs, Wdio, Mocha compatible versions to work together?
Thanks In Advance.
It looks like you are setting the timeout to 20 sec this.timeout(20000);
, and in your it
step the first thing you do is pause for 20 sec app.client.pause(20000)
so that the timeout is reached before you try to setValue. Which would explain the output Error: Timeout of 20000ms exceeded
.
But I experienced a similar error when I was getting started with spectron. I saw application launched properly and I could view login page but when I tried to interact with input fields I got: Error: unable to locate element.
I tried using app.client.pause()
to eliminate the chance of a timing issue but that didn't help.
Spectron does windowByIndex(0)
and you as the test author need to manage the number of windows in your electron application. In our application there are a number of developer plugins (e.g. Devotion, React, MobX) that create their own window.
To diagnose the problem I used a wait strategy that would pause until app.client.getWindowCount()
was equal to 4. But that wasn't a great solution because when new dev plugins were added later it would start to fail.
There was another tricky part. I couldn't just launch the app and simply tell it to focus on the fifth window. Because when the app first was initialized only 3 windows existed. It took a while for the last 2 windows to be initialized, and it took even more time for the page to be rendered. This required us to implement a better wait strategy so that we did not attempt to interact with the app before it was ready.
This solution may or may not work for you, but it has been solid for us. After initializing the client I use a function called waitUntilWindow and pass it the urlPart that is associated with our login page then do app.client.windowByIndex
to set focus on the proper window. At that point I am able to interact with input fields and .setValue
works like normal.
I do apologize if this information has been more confusing than helpful. I have struggled to get going with spectron, but it remains the best option for UI testing electron apps. Grace and peace brother.
await waitUntilWindow(app, 'bundle=login', 'Login window never appeared.', 15000);
export async function waitUntilWindow(app, urlPart, msg, timeoutMs = 15000, interval = 150) {
await app.client.waitUntil(
async () => {
return selectWindow(app, urlPart);
},
timeoutMs,
msg || `Didn't see window with url part ${urlPart} in ${timeoutMs} ms.`,
interval
);
}
// Will return true if found the window with certain urlPart text in URL,
// or false if it did not.
export async function selectWindow(app, urlPart) {
const windowCount = await app.client.getWindowCount();
for (let i = 0; i < windowCount; i++) {
await app.client.windowByIndex(i);
const url = await app.client.getUrl();
if (url.includes(urlPart)) {
return true;
}
}
return false;
}