WinAppDriver canonot find element when new window of desktop application created - javascript

"use strict";
require("./helpers/setup");
var wd = require("wd"),
_ = require('underscore'),
serverConfigs = require('./helpers/appium-servers'),
Q = require('q');
describe("Windows test from Node", function () {
this.timeout(300000);
var driver;
var allPassed = true;
before(function () {
var serverConfig = serverConfigs.local;
driver = wd.promiseChainRemote(serverConfig);
require("./helpers/logging").configure(driver);
var desired = _.clone(require("./helpers/caps").CMS);
return driver
.init(desired);
});
after(function () {
return driver
.quit();
});
afterEach(function () {
allPassed = allPassed && this.currentTest.state === 'passed';
});
it("should open CMS.", function () {
return driver
.elementByName('CharwellDB').doubleclick()
.sleep(20000);
});
it("should login CMS.", function () {
return driver
.elementByAccessibilityId('m_tbUserID').sendKeys("")
.elementByAccessibilityId('m_tbPassword').sendKeys("")
.elementByAccessibilityId('m_btnOk').click();
});
});
Hi, I'm using https://github.com/Clemensreijnen/AppiumOnWindowsWithJS/blob/master/README.md
framework and trying to automate a desktop application. After "should open CMS", a new desktop window open and the winappdriver couldn't locate the element on that window, I tried to work with WindowHandle but not going well with JavaScript, Please give some advise, thanks in advance!

I couldn't find my source code, but the solution is to implement windowHandle and as well as promise in JavaScript.

Related

Javascript Mocha Selenium Test not working

I am trying to run a selenium mocha test to check the title of the website google. I am doing this in the configuration of Web.js and WebTest.js. Here are my classes and I'm not sure if I'm going at this the correct way or not.
Web.js
const {Builder, By, Key, until, WebElement} = require('selenium-webdriver');
var driver = new Builder().forBrowser('internet explorer').build();
var url = 'https://www.google.com/';
function Web() {
var promise = new Promise(function(resolve,reject){
return driver.get(url);
}).then(function(title) {
var title;
title = driver.getTitle().toString();
return title;
}).catch(function(err){
console.log(err);
});
return title;
}
Web.prototype.getTitle = function (title) {
var title = Web();
while (title == null){
title = Web();
}
return (title);
}
module.exports.Web = Web;
WebTest.js
assert = require("assert");
Web = require("../Web.js").Web
describe("A web function", function () {
describe("getting google's title", function () {
it("should return Google", function () {
var result = new Web().getTitle();
assert.equal("Google", result, "But the string " + result + " was returned instead");
});
});
});
I am getting the error "ReferenceError: title is not defined" which leads me to believe I have a scope problem, but I'm not sure how to do this correctly.
Thank you for any help.
This should work:
var webdriver = require("selenium-webdriver");
var DriverFactory = {
create: function (browser) {
return driver = new webdriver
.Builder().forBrowser(browser)
.build();
}
}
module.exports = DriverFactory;
And then use this module in your test
var DriverFactory = require('./driverFactory.js');
var assert = require("chai").assert;
describe("Get title", function () {
this.timeout(40000);
var driver;
before(async function () {
driver = await DriverFactory.create("firefox");
});
after(async function () {
await driver.quit();
});
it("1.Open Google website", async function () {
await driver.get("https://www.google.com");
});
it("2.The title is 'Google'", async function () {
var title = await driver.getTitle();
assert.equal(title, "Google");
});

Programmatically stopping MongoDB

I am working on an application using Node.JS, Electron. This application will run its own instance of MongoDB. The start up of Mongo is working using the following code:
child = childProcess.exec(`mongod --dbpath ${appConfig.dbConfigPath}`);
However, when the user exits the program, I want to stop mongo. I have tried the following, all taken from MongoDB Documentation
child = childProcess.exec('mongod --shutdown');
and
child = childProcess.exec(`kill -2 ${child.pid}`);
yet neither of these are shutting down the process.
This application is being developed to run on the windows platform.
For clarity, here is my app configuration file. The init() function is executed from within my main.js. The shutdown() is executed in the windowMain.on('close').
calibration.js
'use strict';
const childProcess = require('child_process');
const fileUtils = require('./lib/utils/fileUtils');
const appConfig = require('./config/appConfig');
let child;
class Calibration {
constructor() {}
init() {
createAppConfigDir();
createAppDataDir();
startMongo();
}
shutdown() {
shutdownMongo();
}
}
function createAppConfigDir() {
fileUtils.createDirSync(appConfig.appConfigDir);
}
function createAppDataDir() {
fileUtils.createDirSync(appConfig.dbConfigPath);
}
function startMongo() {
child = childProcess.exec(`mongod --dbpath ${appConfig.dbConfigPath}`);
console.log(child.pid);
}
function shutdownMongo() {
console.log('inside shutdownMongo');
//This is where I want to shutdown Mongo
}
module.exports = new Calibration();
main.js
'use strict'
const { app, BrowserWindow, crashReporter, ipcMain: ipc } = require('electron');
const path = require('path');
const appCalibration = require('../calibration');
appCalibration.init();
const appConfig = require('../config/appConfig');
let mainWindow = null;
ipc.on('set-title', (event, title) => {
mainWindow.setTitle(title || appconfig.name);
})
ipc.on('quit', () => {
app.quit();
})
// Quit when all windows are closed.
app.on('window-all-closed', function() {
if (process.platform != 'darwin') {
app.quit();
}
});
// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
app.on('ready', function() {
// Create the browser window.
mainWindow = new BrowserWindow({ center: true });
mainWindow.maximize();
mainWindow.setMinimumSize(770, 400);
mainWindow.loadURL(path.join(`file://${__dirname}`, '../ui/index.html'));
mainWindow.on('close', () => {
console.log('Inside quit')
appCalibration.shutdown();
app.quit();
});
mainWindow.on('closed', function() {
mainWindow = null;
});
});
Any assistance is greatly appreciated.
You can use Ipc to send orders through your js files.
In your main.js where you defined your electron, you can put this:
ipcMain.on("shutDownDatabase", function (event, content) {
// shutdown operations.
});
Then in some part of your application code, you can put a function like this:
function sendShutdownOrder (content){
var ipcRenderer = require("electron").ipcRenderer;
// the content can be a parameter or whatever you want that should be required for the operation.
ipcRenderer.send("shutDownDatabase", content);
}
Also I think you can use the events of Electron to shut down your db, this listens to the events of your mainWindow created when you start electron
mainWindow.on('closed', function () {
// here you command to shutdowm your data base.
mainWindow = null;
});
For more information about IPC you can see here and information about the events of your window here.
With Paulo Galdo Sandoval's suggestion, I was able to get this to work. However, I needed to get the PID for mongod from Windows Task manager. To do that I added the following function to the application configuration js file
function getTaskList() {
let pgm = 'mongod';
exec('tasklist', function(err, stdout, stderr) {
var lines = stdout.toString().split('\n');
var results = new Array();
lines.forEach(function(line) {
var parts = line.split('=');
parts.forEach(function(items) {
if (items.toString().indexOf(pgm) > -1) {
taskList.push(items.toString().replace(/\s+/g, '|').split('|')[1])
}
});
});
});
}
I also declared an array variable to place the located PID in. Then I updated my shutdown function
function shutdownMongo() {
var pgm = 'mongod';
console.log('inside shutdownMongo');
taskList.forEach(function(item) {
console.log('Killing process ' + item);
process.kill(item);
});
}
With this I am now able to start and stop Mongo as my application starts up and closes.
Thanks all

'ReferenceError: driver is not defined' when I try to call a function from a loadable file

Good day.
In JS/node I'm new.
I'm does made two functions from main code into a separate file and now I can not connect it to the main.
If I fighting over this issue. Help me plz. Something I'm doing wrong.
Here are the features that made:
exports.loadRegistrationForm = function() {
driver.get('http://somesite');
driver.getTitle().then(function(title){
if("sometitle"===title){
driver.findElement(webdriver.By.xpath('html/body/div/header/div/div/div[2]/div[2]/a[1]'))
.click();
};
});
driver.wait(function(){
return driver.isElementPresent(webdriver.By.name('fos_user_registration_form[email]'));
}, 3000, 'Failed to load Registration form');
}
exports.fillingRegistrationForm = function(inputEmail, inputPassword, errElement, errMessage){
driver.findElement(webdriver.By.name('fos_user_registration_form[email]'))
.sendKeys(inputEmail);
driver.findElement(webdriver.By.name('fos_user_registration_form[plainPassword]'))
.sendKeys(inputPassword);
driver.findElement(webdriver.By.id('btn-submit')).click();//сабмит
driver.wait(function(){
return driver.isElementPresent(webdriver.By.xpath(errElement));
}, 3000, 'Элемент не найден');
var flow = webdriver.promise.controlFlow();
function getErrObject(){
errObject = driver.findElement(webdriver.By.xpath(errElement))
.getText()
}
flow.execute(getErrObject).then(function(){
if(errObject.value_ === errMessage){
assert.equal(errObject.value_, errMessage);
console.log('OK')
};
});
}
Here are trying to rewrite part of the core functions:
var assert = require("assert")
var webdriver = require('selenium-webdriver');
var driver = new webdriver.Builder().
withCapabilities(webdriver.Capabilities.chrome()).
build();
var loadRegistrationForm = require('reusable_function').loadRegistrationForm;
var fillingRegistrationForm = require('./reusable_function').fillingRegistrationForm
describe('Check the Email field of the registration form.', function(){
it('Enter an already registered Email', function(done){
var inputEmail = '123#ya.ru';
var inputPassword = '12345678Aa';
var errElement = "//*[#class='form-errors server-error']";
var errMessage = 'Email already in use';
loadRegistrationForm();
fillingRegistrationForm(inputEmail, inputPassword, errElement, errMessage);
return done();
});
});
In the console error:
ReferenceError: driver is not defined
at exports.loadRegistrationForm (C:\Program Files\nodejs\test\reusable_fun
ction.js:9:5)
at Context.<anonymous> (C:\Program Files\nodejs\test\test2_mocha.js:15:9)
at callFnAsync (C:\Users\Valentine11\AppData\Roaming\npm\node_modules\moch
a\lib\runnable.js:306:8)
at Test.Runnable.run (C:\Users\Valentine11\AppData\Roaming\npm\node_module
s\mocha\lib\runnable.js:261:7)
at Runner.runTest (C:\Users\Valentine11\AppData\Roaming\npm\node_modules\m
ocha\lib\runner.js:421:10)
at C:\Users\Valentine11\AppData\Roaming\npm\node_modules\mocha\lib\runner.
js:528:12
at next (C:\Users\Valentine11\AppData\Roaming\npm\node_modules\mocha\lib\r
unner.js:341:14)
at C:\Users\Valentine11\AppData\Roaming\npm\node_modules\mocha\lib\runner.
js:351:7
at next (C:\Users\Valentine11\AppData\Roaming\npm\node_modules\mocha\lib\r
unner.js:283:14)
at Immediate._onImmediate (C:\Users\Valentine11\AppData\Roaming\npm\node_m
odules\mocha\lib\runner.js:319:5)
What am I doing wrong? Incorrectly write access functions from loadable module? How does it right?
Great thanks.
Upd. Okay I find answer.
Every module in JS have own scope. In module reusable_function no driver variable, hence the error not defined. Driver is a variable in the main module, but it is invisible to the module reusable_function, because it is not included in the scope. So I have defined a variable driver in the module reusable_function and removed this variable from the main module. To delete a variable from the main driver module does not disturb his work, because the variable driver cache and made available during the import module reusable_function.
Reusable_function:
var assert = require("assert")
var webdriver = require('selenium-webdriver');
var driver = new webdriver.Builder().
withCapabilities(webdriver.Capabilities.chrome()).
build()
exports.loadRegistrationForm = function(){
driver.get('http:...');
driver.getTitle().then(function(title){
if("..."===title){
driver.findElement(webdriver.By.xpath('html/body/div/header/div/div/div[2]/div[2]/a[1]'))
.click();
};
});
driver.wait(function(){
return driver.isElementPresent(webdriver.By.name('fos_user_registration_form[email]'));
}, 3000, 'Failed to load Registration form');
};
exports.fillingRegistrationForm = function(inputEmail, inputPassword, errElement, errMessage){
driver.findElement(webdriver.By.name('fos_user_registration_form[email]'))
.sendKeys(inputEmail);
driver.findElement(webdriver.By.name('fos_user_registration_form[plainPassword]'))
.sendKeys(inputPassword);
driver.findElement(webdriver.By.id('btn-submit')).click();//сабмит
driver.wait(function(){
return driver.isElementPresent(webdriver.By.xpath(errElement));
}, 3000, 'Element not found');
var flow = webdriver.promise.controlFlow();
function getErrObject(){
errObject = driver.findElement(webdriver.By.xpath(errElement))
.getText()
}
flow.execute(getErrObject).then(function(){
if(errObject.value_ === errMessage){
assert.equal(errObject.value_, errMessage);
console.log('OK')
};
});
};
Main module (part of):
var webdriver = require('selenium-webdriver');
var flow = webdriver.promise.controlFlow();
var loadRegistrationForm = require('./reusable_function').loadRegistrationForm
var fillingRegistrationForm = require('./reusable_function').fillingRegistrationForm
describe('Check out Email form field.', function(){
it('Enter already register Email', function(done){
var inputEmail = '123#ya.ru';
var inputPassword = '12345678Aa';
var errElement = "//*[#class='form-errors server-error']";
var errMessage = 'Email already in use';
loadRegistrationForm();
fillingRegistrationForm(inputEmail, inputPassword, errElement, errMessage);
flow.execute(function(){
return done();
});
});
});
Its work.
You have a random funtion execute right above the error line which ends without any code. Remove this and it will work.

Socket not working on jQuery Mobile events

I've just started developing an application with javascript for fxos using jQuery Mobile and already got stuck with a framework related problem. For my app I need to use tcp communication provided by mozilla API (mozTCPSocket), it works well when I run it outside from JQM events, but when I do the socket.open() call from a JQM event (eg. pageshow) it looks like the socket object is being killed after each call.
Here is my code:
window.addEventListener('DOMContentLoaded', function() {
'use strict';
var socket;
var host = "someserver";
var port = 6667;
//connect(); // when calling from here, connection works fine
$(document).bind("pageshow", function(e) {
if (typeof e.currentTarget.URL==="string") {
var haystack = $.mobile.path.parseUrl(e.currentTarget.URL);
var needle = /^#server/;
if (haystack.hash.search(needle)!==-1) {
connect(); // ...from here is failing
}
}
});
function connect() {
socket = navigator.mozTCPSocket.open(host,port);
}
socket.ondata = function (event) {
var data = event.data;
var lines = data.split('\r\n');
for (var i=0;i<lines.length;i++) {
if (lines[i].length>0) console.log(lines[i]);
}
}
});
What could be going wrong?
What's certainly wrong here is this:
socket.ondata = function (event) {
var data = event.data;
var lines = data.split('\r\n');
for (var i=0;i<lines.length;i++) {
if (lines[i].length>0) console.log(lines[i]);
}
}
You're setting the ondata method on an undefined object. Which means that any call to connect() later won't have any effect anyway. Also as you're defining a method of an undefined object, the method above probably is crashing.
You should rewrite your code to something like this.
window.addEventListener('DOMContentLoaded', function() {
'use strict';
var socket;
var host = "someserver";
var port = 6667;
//connect(); // when calling from here, connection works fine
$(document).bind("pageshow", function(e) {
if (typeof e.currentTarget.URL==="string") {
var haystack = $.mobile.path.parseUrl(e.currentTarget.URL);
var needle = /^#server/;
if (haystack.hash.search(needle)!==-1) {
connect(); // ...from here is failing
}
}
});
function connect() {
socket = navigator.mozTCPSocket.open(host, port);
socket.ondata = onData;
}
function onData (event) {
var data = event.data;
var lines = data.split('\r\n');
for (var i=0;i<lines.length;i++) {
if (lines[i].length>0) console.log(lines[i]);
}
}
});

assertion selenium webdriver node js

I am trying to run assertion for testing with selenium webdriver through node js but it says undefined, I get the page title which is URL of the page then assert it, looks like I have to import sth for assertion, please help, also please tell me if selenium works fine with node js here is my code:
var webdriver = require('selenium-webdriver'),
//var test = require('selenium-webdriver/testing'),
nodeThen = require('node-then');
var assert = require('assert');
//var jsdom = require("jsdom");
//var document = require('jquery');
var xpath = require('xpath');
//var driver = new webdriver.Builder().
// withCapabilities(webdriver.Capabilities.chrome()).
//build();
function createDriver() {
var driver = new webdriver.Builder()
.usingServer('link')
.withCapabilities(webdriver.Capabilities.chrome())
.build();
driver.manage().timeouts().setScriptTimeout(10000);
return driver;
}
var driver = createDriver();
var By = webdriver.By;
driver.get("URL")
.then(function(){
driver.sleep(10000);
var element=driver.findElement(By.id("get-started"));
element.click();
})
.then(function(){`enter code here`
return driver.getTitle();
})
.then(function(title) {
//console.log(title);
//driver.manage().timeouts().setScriptTimeout(50000);
if (title == ('URL')) {
console.log("pass");
}
//
I was searching for the same issue and I found this snippet which is working for me
driver.findElement(By.id('elementId'))
.getText().then(textValue => {
assert.equal('tested string', textValue);
});
I found it in the examples files of selenium-webdriver's github repo
Did you install asserts? The command would be npm install asserts. Also, you need var Asserts = require('asserts');
This is the example you are looking for
// Require chai.js expect module for assertions
const chai = require('chai');
const expect = require('chai').expect;
// Application Server
const serverUri = '0.0.0.0:3000';
// Official selenium webdriver testing setup
const webdriver = require('selenium-webdriver');
describe('basic test', function () {
let driver;
before(() => {
// Start of test use this
driver = new webdriver.Builder().
withCapabilities(webdriver.Capabilities.chrome()).
build();
console.log("Selenium Webdriver Chrome Started");
});
after(function(){
// End of test use this.
driver.quit();
});
it('should be on correct page', function (done) {
this.timeout(10000);
driver.get(serverUri);
driver.getTitle().then(function(title) {
expect(title).to.equal('Some String Here');
done();
console.log("Selenium Webdriver Chrome Shutdown");
})
});
});

Categories