WebDriverjs not loading url when used with mocha - google-chrome

I'm currently working on writing some automated tests for a web app, using WebDriverJs and Mocha. When I remove anything relating to Mocha, it runs fine and does exactly what I'm expecting. However, as soon as I introduce the mocha elements into my code, Chrome will open, but then won't load the url and the test times out.
The code I'm using (with mocha implemented) is as follows:
"use strict";
var assert = require('assert');
var test = require('selenium-webdriver/testing');
var webdriver = require('selenium-webdriver');
var driver = new webdriver.Builder().usingServer().withCapabilities({'browserName': 'chrome' }).build();
before(function() {
driver.get('http://127.0.0.1:3000/');
});
test.describe('Login', function() {
test.it('should work', function()
{
var passLoginTest = require('./PassLoginTest');
passLoginTest(webdriver, driver).then(function(loggedIn){
assert.isTrue(loggedIn, 'successfully logged in');
});
driver.quit();
});
});
I've also tried using driver.get('http://127.0.0.1:3000/); outside of a before block, but it had the same result. I'm using Mocha v. 2.2.1 and Webdriver 2.45.1.

I ran into this too, also when using jasmine instead of mocha.
I experimented a bit with the versions of mocha and selenium-webdriver.
It turns out version 2.43 of selenium webdriver and up have this issue, below works well for me. So I settled on the last version that works ok. My package.json now has
...
"selenium-webdriver": "~2.42.1",
"mocha": "~2.2.4",
...

You should not be calling before "naked" like you do. You should do like you do with describe and it and use the version that is provided by selenium-webdriver/testing so:
test.before(function() {
driver.get('http://127.0.0.1:3000/');
});
The version of these calls provided by selenium-webdriver/testing are modified to wait for the driver to do its work before moving on. The "stock" (which I called "naked" above) version of these calls would require at a minimum that you return a promise or that you use a callback.

Related

Issue listening for custom event via puppeteer

I am currently working on a GitLab CI test environment and I have a test harness which we use to test our SDK. I have gone about setting up a custom event that is fired on the page which designates the end of the test run. In my puppeteer implementation I am wanting to listen for this custom event "TEST_COMPLETE".
I have not been successful in getting this to work so I figured I would at least make sure the custom-event.js example on the puppeteer repo worked and there too I am not seeing what I believe I should be getting. I cloned the main repo below and performed an npm install. When I execute the js test below, setting headless:false and don't close the browser, I do not see any log in console that shows any custom event being fired.
It is my understanding that I should see some console event message with 'fired' and then 'app-ready' event and info, but this is not the case. Even if I interact with the page I don't see anything outside of some 'features_loaded' and 'features_unveil' logs.
https://github.com/puppeteer/puppeteer/blob/main/examples/custom-event.js
Anyone able to get the expected behavior on this code today? Not sure if this worked previously and has broke since or I am just doing something wrong. Any info would be of great help, Thanks!
Not sure if this is what you need, but I can get the message 'TEST_COMPLETE fired.' in Node.js console with this simplified code (puppeteer 8.0.0):
import puppeteer from 'puppeteer';
const browser = await puppeteer.launch();
try {
const [page] = await browser.pages();
await page.goto('https://example.org/');
await page.exposeFunction('onCustomEvent', async (type) => {
console.log(`${type} fired.`);
await browser.close();
});
await page.evaluate(() => {
document.addEventListener('TEST_COMPLETE', (e) => {
window.onCustomEvent('TEST_COMPLETE');
});
document.dispatchEvent(new Event('TEST_COMPLETE'));
});
} catch (err) { console.error(err); }

google.script.run in html UI doesn' t call server function

I have a couple of scripts that don't work anymore although I didn't make any change.
I don't spend a lot of time programming these last month so I didn't notice it right away...
Here is a simplified code that used to work and that doesn't, I can't figure out my error.
The HTML part is entirely built on server side since it's a very simple code (runs from a spreadsheet).
function myFunction() {
var doc = '<body style="font-family:arial,sans;font-size:12pt">';
doc+='<select id="target" multiple style="font-family:arial,sans;font-size:12pt">';
doc+='<option value="1">choice 1</option><option value="2">choice 2</option><option value="3">choice 3</option></select><br><br>';
doc+='<input type="button" onClick="processJS()" style="background:#BFA;font-size:12pt" value="Validate"/>';
doc+='<script>function processJS(){var e=document.getElementById("target");var values=Array.from(e.selectedOptions).map(option => option.value);';
doc+='console.log(JSON.stringify(values));google.script.run.withSuccessHandler(function(msg){ window.alert(msg);google.script.host.close;}).processGSTest(values)};</script>';
doc+='</body>';
var ui = HtmlService.createHtmlOutput(doc).setWidth(500).setHeight(250);
SpreadsheetApp.getUi().showModelessDialog(ui, "test");
}
function processGSTest(values){
Logger.log(JSON.stringify(values));
return "processGSTest ok";
}
I get an error in JS console like this when I hit "validate" :
the HTML rendered window looks like this :
EDIT
Following comments (thanks again) I've got a few more informations :
when using another browser the scripts works fine
when using chrome and adding an withFailureHandler it still fails with the same console message without handling the failure (Chrome Version 81.0.4044.122 (Build officiel) (64 bits) on Mac OS High Sierra)
when calling the same function from a custom menu the script works fine even in the same Chrome session
conclusion of this edit : I don't understand the issue :)
Since this post is about a very specific case that does not seem to be reproductible I answer it so it doesn't stay open indefinitely.
In the same time I'll post an issue report on the tracker.
Here is the script I use to show the issue.
The main function (myFunction) reports an error when called from the script editor but works when called from the menu...
This happens only on Chrome Version 81.0.4044.122 (Build officiel) (64 bits) on Mac OS High Sierra 10.13.6, it works normally on Safari, Firefox and even Chrome on Windows 10.
(It works also normally on the same version of Chrome under Mac OS 10.10.5 !! )
function myFunction() {
var doc = '<body style="font-family:arial,sans;font-size:12pt">';
doc+='<select id="target" multiple style="font-family:arial,sans;font-size:12pt">';
doc+='<option value="1">choice 1</option><option value="2">choice 2</option><option value="3">choice 3</option></select><br><br>';
doc+='<input type="button" onClick="processJS()" style="background:#BFA;font-size:12pt" value="Validate"/>';
doc+='<script>function processJS(){var e=document.getElementById("target");var values=Array.from(e.selectedOptions).map(option => option.value);';
doc+='console.log(JSON.stringify(values));google.script.run.withFailureHandler(function err(){window.alert("error triggered by withFailureHandler");})';
doc+='.withSuccessHandler(function(msg){ window.alert(msg);google.script.host.close();}).processGSTest(values)};</script>';
doc+='</body>';
var ui = HtmlService.createHtmlOutput(doc).setWidth(500).setHeight(250);
SpreadsheetApp.getUi().showModelessDialog(ui, "test");
}
function processGSTest(values){
Logger.log(JSON.stringify(values));
return "processGSTest ok";
}
function onOpen(){
var ss = SpreadsheetApp.getActiveSpreadsheet();
var menuEntries = [{name: "test", functionName: "myFunction"}]
ss.addMenu("test",menuEntries);
}
I created a shared spreadsheet for anyone that would want to play with it (read only, make a copy to use)

Programmatically loading a ES6 module with Traceur in web page

I have been using Traceur to develop some projects in ES6. In my HTML page, I include local Traceur sources:
<script src="traceur.js"></script>
<script src="bootstrap.js"></script>
and if I have a module in the HTML afterwards like:
<script type="module" src="foo.js"></script>
Then Traceur loads in that module, compiles it and everything works great.
I now want to programmatically add an ES6 module to the page from within another ES6 module (reasons are somewhat complicated). Here was my first attempt:
var module = document.createElement('script');
module.setAttribute('type', 'module');
module.textContent = `
console.log('Inside the module now!');
`;
document.body.appendChild(module);
Unfortunately this doesn't work as Traceur does not monitor the page for every script tag added, I guess.
How can I get Traceur to compile and execute the script? I guess I need to invoke something on either 'traceur' or '$traceurRuntime' but I haven't found a good online source of documentation for that.
You can load other modules using ES6 import statements or TraceurLoader API for dynamic dependencies.
Example from Traceur Documentation
function getLoader() {
var LoaderHooks = traceur.runtime.LoaderHooks;
var loaderHooks = new LoaderHooks(new traceur.util.ErrorReporter(), './');
return new traceur.runtime.TraceurLoader(loaderHooks);
}
getLoader().import('../src/traceur.js',
function(mod) {
console.log('DONE');
},
function(error) {
console.error(error);
}
);
Also, System.js loader seems to be supported as well
window.System = new traceur.runtime.BrowserTraceurLoader();
System.import('./Greeter.js');
Dynamic module loading is a (not-yet-standardized) feature of System:
System.import('./repl-module.js').catch(function(ex) {
console.error('Internal Error ', ex.stack || ex);
});
To make this work you need to npm test then include BrowserSystem
<script src="../bin/BrowserSystem.js"></script>
You might also like to look into https://github.com/systemjs/systemjs as it has great support for browser loading.
BTW the System object may eventually be standardize (perhaps under a different name) in the WHATWG: http://whatwg.github.io/loader/#system-loader-instance

Cannot read property 'emit' of undefined in gulp-browserify

i am running into a problem. I have created my own seed: https://github.com/damirkusar/leptir-angular-seed with gulp, browserify and more.
Everything worked fine, since i had the good idea to update node from 10.32 to 12.5, i am getting the below error. I think that this is since then. I tried it also on a different machine, same setup, same error.
so, after npm install and bower install i am starting the app with:
gulp
or when trying to build the project with
gulp build
i am getting this error:
leptir-angular-seed/node_modules/gulp-browserify/node_modules/browserify/node_modules/module-deps/index.js:162
rs.on('error', function (err) { tr.emit('error', err) });
^
TypeError: Cannot read property 'emit' of undefined
at ReadStream.<anonymous> (/leptir-angular-seed/node_modules/gulp-browserify/node_modules/browserify/node_modules/module-deps/index.js:162:39)
at ReadStream.emit (events.js:107:17)
at fs.js:1618:12
at FSReqWrap.oncomplete (fs.js:95:15)
Here is also the link to the package.json: https://github.com/damirkusar/leptir-angular-seed/blob/450ffe99943036cd5a670e54ec3884c02bd7bb8a/package.json.
but luckily, karma start executes the tests and all tests are passing..
Maybe some versions are not really supported correctly?
Does anybody have an idea what causes this problem?
-- edit 2015-June-25 14:23
I am using the module which cause the problem in my gulp file like this:
// Browserify task
gulp.task('browserify', function () {
gulp.src(paths.browserify[0])
.pipe(browserify({
insertGlobals: true,
debug: true
}))
// Bundle to a single file
.pipe(concat('bower.js'))
// Output it to our dist folder
.pipe(gulp.dest(paths.destination_public))
.pipe(refresh(lrServer)); // Tell the lrServer to refresh;
gulp.src(paths.browserify[1])
.pipe(browserify({
insertGlobals: true,
debug: true
}))
// Bundle to a single file
.pipe(concat('app.js'))
// Output it to our dist folder
.pipe(gulp.dest(paths.destination_public))
.pipe(refresh(lrServer)); // Tell the lrServer to refresh;
});
which browserifyies these app.js file and its content:
require('./modules/core');
require('./modules/core');
and bower.js with its content:
'use strict';
require('jquery');
require('bootstrap');
require('moment');
require('underscore');
require('angular');
require('angular-animate');
require('angular-bootstrap');
require('angular-bootstrap-tpls');
require('angular-cookies');
require('angular-mocks');
require('angular-resource');
require('angular-ui-router');
require('angular-ui-utils');
require('angular-translate');
require('angular-translate-loader-static-files');
require('angular-translate-loader-url');
require('angular-translate-storage-cookie');
require('angular-translate-storage-local');
thank you so much
"...but in fact, otherwise i am not using this module which causes the error." - damir
modules has dependencies too. it seems to be a problem with one of these modules that are used by an other module.
It could be possible that a module you are using has a dependency on a node component of the old version. Try to get the old back until the bug is fixed.
On a windows machine (instead of mine mac) it showed me a better error message.
I referenced bower packages which where not installed.. but totally forgot to remove it from package.json and bower.js.
so i removed code in the above files which referenced the following packages:
angular-translate-storage-cookie
angular-translate-storage-local
-- UPDATE 27th June 2015 - 22:41 --
I saw that gulp-browserify is blacklisted by gulpjs, so i thought its better to get rid of it, because i faced also problems on windows machines. Instead of using gulp-browserify, i am using plain browserify with vinyl-transform.
First, update your package.json with this:
"browserify": "9.0.4",
"vinyl-transform": "1.0.0"
You see, that i am using exactly these two versions, this is because with newer browserify versions, things are not really working, so to be sure that it works also when i update my packages, i keep them in this versions.
Then lets update our gulp file. We will need to add these two lines:
var browserify = require('browserify'),
transform = require('vinyl-transform');
and my new task looks like this:
gulp.task('browserify', function () {
var browserified = transform(function(filename) {
var b = browserify(filename);
return b.bundle();
});
return gulp.src(paths.browserify)
.pipe(browserified)
.pipe(gulp.dest(paths.destination_public));
});
its now shorter and much cleaner. My paths are configured like this..
var paths = {
...
browserify: ['./public/bower.js', './public/app.js'],
...
destination_public: './dist/'
};
now my seed is working on mac and windows the same way.
https://github.com/damirkusar/leptir-angular-seed

Replacing page functions via userscript in Chrome?

I've created a Greasemonkey script which replaces a page function:
(function() {
var oldFunc = func;
func = function() {
oldFunc();
// other stuff
};
)();
I had always intended this script to work in both Gresemonkey and Chrome and had read that Chrome doesn't support unsafeWindow, so have been injecting the script into the page by converting the function to a string and using setTimeout:
setTimeout("(function(){var old=func;func=function(){old();/*other stuff*/}}())", 0);
This works perfectly well in Greasemonkey, but gives me absolutely nothing in Chrome. It clearly isn't firing, but nothing appears in the log, either. I have tried a number of other injection styles, but can't get anything to work. (For testing, I also added an alert() to the top of the function.)
setTimeout(..., 0) — nothing
Running the function in-scope, without injection into the page — no alert, but "func is not defined" in console
document.href = "javascript:..." — nothing
document.body.addEventListener("load", ...) — nothing
All of these are with #run-at document-end.
Unfortunately, this being my first Chrome userscript, I'm at a loss as to how to debug it, even after an hour or so of Googling and poking around SO. Any help?
Actual script, currently working in Greasemonkey: http://pastebin.com/HtLVjYHg
In the end, the only technique I found which worked in Chrome was to create a <script> node using DOM methods. Fortunately, this seems to work equally well in Firefox and Opera and is made fairly painless by <func>.toString():
function embed() {
var oldFunc = window.func;
window.func = function() {
oldFunc();
// other stuff
};
}
var inject = document.createElement("script");
inject.setAttribute("type", "text/javascript");
inject.appendChild(document.createTextNode("(" + embed + ")()"));
document.body.appendChild(inject);
Final script: http://userscripts.org/scripts/review/84394