How can I use waitForElementVisible without reporting the result to the console? - selenium

Using nightwatch.js how can I wait for an element to load without the result printing to the console?
I do not want waits to appear in my reports, only normal assertions.
The following code will output 'Waiting for settings menu to load' to the console. If no custom message is used, the default message is 'Element #editMenuContentsButton was visible after xxxx milliseconds':
/**Clicks the settings menu and logs the action.
* #method clickSettings
*/
clickSettings: function () {
this.waitForElementVisible('#settingsSettings', 5000, 'Waiting for settings menu to load');
this.click('#settingsSettings', function () {
testUtil.logAction('Click Gallery settings menu');
});
this.api.pause(1000);
return this;
}

I found a solution to this by simply commenting out the following code in the waitForElement.js file (found in: lib/api/element-commands)
WaitForElement.prototype.pass = function(result, defaultMsg, timeMs) {
this.message = this.formatMessage(defaultMsg, timeMs);
//this.client.assertion(true, null, null, this.message, this.abortOnFailure);
return this.complete(result);
};

Related

Change ICN contentViewer's tab title in split pane mode?

I need to change the "title" for each document shown in ICN Viewer, dynamically, at runtime. I'll read the new viewer tab title from the document properties
ENVIRONMENT: ICN 2.0.3 CM8.5 WAS 8.5.5
CODE SO FAR:
I found a PARTIAL solution by hooking "ecm.model.desktop, onChange":
aspect.after(ecm.model.desktop, 'onChange', function() {
var contentViewer = dijit.byId('contentViewer');
if (contentViewer) {
var viewerTabTitleDef = new ViewerTabTitleDef ();
contentViewer.mainTabContainer.getChildren().forEach(function(child) {
viewerTabTitleDef.changeTitle(viewerTabTitleDef.self,
child.controlButton, child.contentViewerPane.viewerItem.item);
});
...
I was able to extend this for subsequent documents opened in the same viewer, and optimized by "removing()" the handler after this initial call. Here is the complete code:
var kill = aspect.after(ecm.model.desktop, 'onChange', function() {
var contentViewer = dijit.byId('contentViewer');
// "contentViewer" will be "unknown" unless viewer invoked
console.log('onChange: contentViewer', contentViewer);
if (contentViewer) {
console.log("new ViewerTabTitleDef()...");
kill.remove();
var viewerTabTitleDef = new ViewerTabTitleDef ();
contentViewer.mainTabContainer.getChildren().forEach(function(child) {
// For initially opened tabs
console.log('initially opened: child', child);
viewerTabTitleDef.changeTitle(viewerTabTitleDef.self, child.controlButton, child.contentViewerPane.viewerItem.item);
});
aspect.after(contentViewer.mainTabContainer, 'addChild', function(child) {
// For tabs added after the viewer was opened
console.log('subsequently opened: child', child);
viewerTabTitleDef.changeTitle(viewerTabTitleDef, child.controlButton, child.contentViewerPane.viewerItem.item);
}, true);
} // end if contentViewer
}); // end aspect.after(onChange desktop)
CURRENT PROBLEM:
Q: How can I change the label for a split tab (either vertical or horizontal)?
So far, I have NOT been able to find any event for any ICN/ECM widget or object variable that I can trigger on.
Thank you in advance!
===============================================
ADDENDUM:
Many thanks to Ivo Jonker, for his suggestion to modify the widget prototype's
"getHtmlName()" method. It worked!
Specifically:
I'm invoking this code from an ICN plugin. I set event handlers in my plugin's base .js file, but it actually gets invoked in the new, separate viewer window.
The original prototype looked like this:
getHtmlName: function() {
var methodName = "getHtmlName";
this.logEntry(methodName);
var displayName = this.item.getDisplayValue("{NAME}");
if (displayName == "") {
displayName = this.item.name;
}
var htmlName = entities.encode(displayName);
this.logExit(methodName);
return htmlName;
},
Per Ivo's suggestion, I overrode the prototype method like this:
myPluginDojo.viewerTabTitleDef = viewerTabTitleDef;
...
ecm.widget.viewer.model.ViewerItem.prototype.getHtmlName = function () {
console.log("NEW getHtmlName()...");
var displayName = myPluginDojo.viewerTabTitleDef.getTitle(this.item);
return displayName;
};
If i understand you correctly, you want to show a different tab-title (instead of the document title) in the navigator viewer whenever a doc is opened?
How about this:
Every document you open in the viewer is wrapped in a ecm.widget.viewer.model.ViewerItem which exposes the getHtmlName that returns the name used in the tab.
Your solution would be to implement your own getHtmlName.
Unfortunately though, the ViewerItem is constructed in the ecm.widget.viewer.ContentViewer#_open and then passed to the ecm.widget.viewer.ContentViewer#_openTab. So you'll either violate best practice by mingling with IBM private method's, or you'll go for a generic approach and just replace the ecm.widget.viewer.model.ViewerItem.prototype.getHtmlName

How to assert run loop DOM changes inside an Ember test

I am writing test for Ember app written in Ember 1.6.
Inside a controller I have a function executed upon promise success:
var me = this;
function onSuccess(result) {
printSuccessMessage();
Ember.RSVP.all(promises).then(function(value) {
Ember.run.later(this, function() {
clearMessages();
}, 5000);
});
}
Then, inside the test, I am trying to assert that the success message appears:
fillIn('#MyInputField', 'Some text');
click('#MyButton');
andThen(function() {
strictEqual(find('[data-output="info-message"]').text().trim().indexOf('Done!') >= 0, true, 'Expected success message!');
});
But the problem is, that after the click, andThen is waiting for a run loop to finish. So after this click, andThen waits 5 seconds and then executes assertions.
In that moment clearMessages() is already executed, the message div is cleared, and the test fails.
Any idea how to assert that this message has certain text?
If you are willing to have a condition in your code, that checks whether or not Ember is in testing mode, you can toggle the Ember.testing value in your test, and then clear or not clear the message in your controller, based on that value. Your tests can then assert that the message is cleared in one instance, and showing in the other.
In the controller's onSuccess call, observe the Ember.testing condition:
onSuccess(message) {
this.printSuccessMessage(message);
if (Ember.testing) { // <-- HERE
// during testing
return; // don't clear the message and assert that it's there
} else {
// during dev, live in production, or Ember.testing === false
this.clearMessages(); // clear the message, and assert that it's gone
}
},
In the acceptance test for setting the message, since Ember.testing is true by default, the controller will not clear the message, and the following test will succeed:
test('setting the message', function(assert) {
visit('/messages');
fillIn('input.text-input', 'Some text');
click('button.clicker');
// while Ember.testing is `true` (default), do not remove message
andThen(() => {
assert.equal(find('div.info-message').text(),
'Done!',
'The message was set properly.');
});
});
In the test that follows, observe the toggling of false for Ember.testing, which will "emulate" live dev or production conditions for the controller. The controller will clear the message, as normal, and this test will also succeed:
test('clearing the message', function(assert) {
visit('/messages');
fillIn('input.text-input', 'Some text');
andThen(() => {
Ember.testing = false;
});
click('button.clicker');
// while Ember.testing is `false`, remove message, as normal, as in dev or prod
andThen(() => {
assert.equal(find('div.info-message').text(),
'',
'The message has been cleared.');
});
// reset Ember.testing to its default
andThen(() => {
Ember.testing = true;
});
});
Please note, Ember.testing is reset to its default value of true as soon as the false condition is no longer needed. This is important because Ember run loop behavior is different during testing by design.
In this solution, some code has been refactored, to isolate concerns and make it easier to unit test. Here's an Ember Twiddle to demonstrate, which was inspired, in part, by this article on Medium.

Unable to find element and send keys

So just a brief overview, I'm unable to send keys to a edit text field for android. I've successfully sent keys to this element via browser but in order to test the mobile application fully, I'd like to run e2e tests on a device using Appium.
I've successfully got Appium to click button elements but am having a hard time getting it to send keys to an edit field element.
Am I able to find elements by model when testing with android as I have set in my forgot-pin-page.js?
pin-reset-page.js
var pinResetPage = function() {
describe('The Reset Pin Flow', function () {
forgotPinPage = forgotPinPageBuilder.getForgotPinPage(),
describe('The Forgot Pin Page', function () {
it('should allow the user to enter their MSISDN and continue',
function () {
forgotPinPage.enterMsisdn('123123123');
forgotPinPage.doForgotPin();
expect(securityPage.isOnSecurityPage()).toBe(true);
});
});
}
forgot-pin-page.js
'use strict';
var ForgotPin = function () {
var forgotPinPageContent = element(by.id('forgot')),
msisdnInput = element(by.model('data.msisdn')),
return {
enterMsisdn: function (msisdn) {
return msisdnInput.sendKeys(msisdn);
}
};
module.exports.getForgotPinPage = function () {
return new ForgotPin();
};
The error i'm getting is
? should allow the user to enter their MSISDN and continue
- Error: Timeout - Async callback was not invoked within timeout spe
cified by jasmine.DEFAULT_TIMEOUT_INTERVAL.
Not sure if this is the correct solution but it worked for me. I downgraded jasmine2 to jasmine and that seemed to resolved the async timeouts I was having.

Disable the escape key in dojo

I have a requirement to disable the escape key when the dialog is open.currently when i click the escape button the dialog closes and the transaction is submitting.I tried the following code snippet but its not working chrome.
dojo.connect(dialog, "onKeyPress", function(e){
var key = e.keyCode || e.charCode;
var k = dojo.keys;
if (key == k.ESCAPE) {
event.preventDefault();
d.stopEvent(event);
}
});
Could you please help on this..i have searched a lot and havent found a suitable solution for my problem.
Thanks inadvance..
Dojo uses the _onKey event for accessibility. You can override it by using:
dialog._onKey = function() { }
I wrote an example JSFiddle, hitting the Escape key should not work anymore.
In the event you want to override the escape key in all dialogs (rather than a particular instance), you can use dojo/aspect:
require(['dojo/aspect', 'dijit/Dialog'], function (Aspect, Dialog) {
Aspect.around(Dialog.prototype, '_onKey', function (original) {
return function () { }; // no-op
});
});
You can create an extension for the Dialog widget like this in a new file:
define(["dojo/_base/declare", "dijit/Dialog"],
function(declare, Dialog){
return declare(Dialog, {
//Prevents the 'ESC' Button of Closing the dialog
_onKey: function() { }
});
});
save the file into dojo Directory (say: dojo/my/my_dialog.js),
and instead of calling: 'dijit/Dialog', just call: 'my/my_dialog'.
this will save you the hard work of editing each Dialog call,
And the same thing to the "dojox/widget/DialogSimple" Widget.

Detecting browser print event

Is it possible to detect when a user is printing something from their browser?
To complicate matters, if we are presenting a user with a PDF document in a new window is it possible to detect the printing of that document ( assuming the user prints it from the browser window)?
The closest I've been able to find is if we implement custom print functionality (something like this) and track when that is invoked
I'm primarily interested in a solution that works for internet explorer (6 or later)
You can now detect a print request in IE 5+, Firefox 6+, Chrome 9+, and Safari 5+ using the following technique:
(function() {
var beforePrint = function() {
console.log('Functionality to run before printing.');
};
var afterPrint = function() {
console.log('Functionality to run after printing');
};
if (window.matchMedia) {
var mediaQueryList = window.matchMedia('print');
mediaQueryList.addListener(function(mql) {
if (mql.matches) {
beforePrint();
} else {
afterPrint();
}
});
}
window.onbeforeprint = beforePrint;
window.onafterprint = afterPrint;
}());
I go into more detail into what this is doing and what it can be used for at http://tjvantoll.com/2012/06/15/detecting-print-requests-with-javascript/.
For Internet Exploder, there are the events window.onbeforeprint and window.onafterprint but they don't work with any other browser and as a result they are usually useless.
They seem to work exactly the same for some reason, both executing their event handlers before the printing window opens.
But in case you want it anyway despite these caveats, here's an example:
window.onbeforeprint = function() {
alert("Printing shall commence!");
}
For anyone reading this on 2020.
The addListener function is mostly deprecated in favor of addEventListener except for Safari:
if (window.matchMedia) {
const media = window.matchMedia("print");
const myFunc = mediaQueryList => {
if (mediaQueryList.matches) {
doStuff();
}
};
try {
media.addEventListener("change", myFunc);
} catch (error) {
try {
media.addListener(myFunc);
} catch (error) {
console.debug('Error', error)
}
}
}
Reference: This other S.O question
If it's only for tracking purposes, perhaps you could set a background url in CSS print media to a server page (.aspx, .php, etc) and then do something on the server?
This guy claims it works.
This is not as versitile as TJ's solution, but it may be less buggy (see TJs blog post for issues he found) when only tracking is needed.