nightwatch waitForElementVisible and assert.visible not working - json

am new to nightwatch
I just copy the first code form http://nightwatchjs.org/
Below showing the code
module.exports = {
'Demo test Google' : function (client) {
client
.url('http://www.google.com')
.waitForElementVisible('body', 1000)
.assert.title('Google')
.assert.visible('input[type=text]')
.setValue('input[type=text]', 'rembrandt van rijn')
.waitForElementVisible('button[name=btnG]', 1000)
.click('button[name=btnG]')
.pause(1000)
.assert.containsText('ol#rso li:first-child',
'Rembrandt - Wikipedia')
.end();
}
};
And getting Failure
error result
.waitForElementVisible('body', 20000) is showing error and also .assert.visible('input[type=text]') is getting fail

Actually the problem is that piece of code is a bit older, and google changed few things on their search page. So for testing purposes you could try it out with the following code:
module.exports = {
'Demo test Google' : function (client) {
client
.url('http://www.google.com')
.waitForElementVisible('body', 5000)
.assert.title('Google')
.assert.visible('input[type=text]')
.setValue('input[type=text]', ['rembrandt van rijn', client.Keys.ENTER])
.waitForElementVisible('button[name=btnG]', 5000)
.click('button[name=btnG]')
.pause(3000)
.assert.containsText('#rso > div > div > div:nth-child(2) > div > div > h3 > a',
'Rembrandt - Wikipedia')
.end();
}
};
It is edited and should work fine, test it and let me know if it is working for you.

Try to change this line of code from
"start_process" : false
to
"start_process" : true

Related

How can I find the place in my code or page where the location is set?

I tried global event listeners pane in Chrome DevTools, I tried to put a debugger; inside document/window.addEventListener("unload", ...) and it is not working.
I tried to step over the statements in the file main.ts and nothing is breaking the code in there when I click on a link that should open another page than the one it is opening. I checked its HTML attributes and the correct URL is set in its href attribute. The link has a single class which is not used to open another page in the page's code as far as I know.
I also searched for all the places in my code where the (window.)location is changed.
I also updated npm packages using npm update.
I use KnockOut.js and I have this static HTML for the links that go to wrong pages:
<ul class="main-nav" data-bind="foreach: mainMenuItems">
<li>
<a data-bind="attr: { href: url, title: text }, text: text, css: { active: $data == $root.activeMenuItem() }"></a>
<div class="bg"></div>
</li>
</ul>
And this is a part of the TypeScript code (sorry for the ugly code, it is WIP):
let vm = new PageViewModel(null, "home", () => {
sammyApp = $.sammy(function () {
// big article URLs w/ date and slug
this.get(/\/(.+)\/(.+)\/(.+)\/(.+)\/(.*)[\/]?/, function() {
vm.language("ro");
vm.isShowingPage(false);
vm.isShowingHomePage(false);
let slug : string = this.params['splat'][3];
vm.slug(slug);
console.log('logging', { language: vm.language(), slug: vm.slug() });
vm.fetch();
vm.isShowingContactPage(false);
vm.activeMenuItem(vm.getMenuItemBySlug(slug));
});
// any other page
this.get(/\/ro\/(.+)\//, function () {
console.log('pseudo-navigating to /ro/etc.');
vm.language("ro");
vm.isShowingPage(true);
vm.isShowingHomePage(false);
let slug : string = this.params["splat"][0];
//slug = slug.substr(0, slug.length - 1);
if (slug !== 'contact') { // this page is in the default HTML, just hidden
vm.slug(slug);
vm.fetch();
vm.isShowingContactPage(false);
} else {
vm.isShowingContactPage(true);
window.scrollTo(0, 0);
}
vm.activeMenuItem(vm.getMenuItemBySlug(slug));
});
this.get(/\/en\/(.+)\//, function () {
console.log('pseudo-navigating to /en/etc.');
vm.language("en");
vm.isShowingPage(true);
vm.isShowingHomePage(false);
let slug : string = this.params["splat"][0];
//slug = slug.substr(0, slug.length - 1);
if (slug !== 'contact') { // this page is in the default HTML, just hidden
vm.slug(slug);
vm.fetch();
vm.isShowingContactPage(false);
} else {
vm.isShowingContactPage(true);
, () => {
uuuuucons
}9 function
window.scrollTo(0, 0);
}
vm.activeMenuItem(vm.getMenuItemBySlug(slug));
});
// the home page
this.get("/", function () {
console.log(`pseudo-navigating to /${vm.language()}/home`);
sammyApp.setLocation(`/${vm.language()}/home`);
});
});
sammyApp.run();
});
I have this code that catches the click event:
$("a").on("click", () => {
debugger;
});
But after this finding I do not know what I can do to find the source of the problem.
When the click is catched by the 3 LOCs above, I get this:
What could be the issue?
Thank you.
Update 1
After seeing these questions and their answers (the only thing I did not try was using an iframe):
How can I find the place in my code or page where the location is set?
Breakpoint right before page refresh?
Break javascript before an inline javascript redirect in Chrome
If I have a page for which I check the beforeunload and unload event checkboxes in the Event Listener Breakpoints pane in Chrome DevTools' tab Sources, and I click on a link which should not reload the page but it does, and the two breakpoints (beforeunload and unload) are not triggered in this process, what should I do next?
Is this a known bug? If so, can someone give me an URL?
Thank you.

How can I asynchronously render images using HTML canvas (and vue.js)?

I have a program that keeps track of a number. If you get above your goal number, you visit a page that shows how much extra you have stored up. On that page is a gumball machine, and depending on the number of excess you have stored up, a certain number of gumballs appear in side the machine. Everything works fine, but about 1 out of every 3 page loads, the gumballs appear first, and then the machine appears, covering all of the gumball images first.
This is being done through vue.js Here is the code I have:
created () {
this.$http.get('/gumballs/' + this.$auth.user().id).then(res => {)
this.createCanvas()
})
}
*******
createCanvas () {
// general canvas properties...
// gumball machine properties
this.createGumbllMachine(canvas.width, ctx, (err, succ) => {
if (err) {
console.log(err)
} else if (succ) {
this.createGumballs(canvas.width, ctx)
}
})
}
**********
createGumballMachine (width, ctx, cb) {
const imgObj = document.createElement('img')
imgObj.src = machineImg
imgObj.onload = () => {
ctx.drawImage(imgObj, (width / 2) - 350, 100)
}
return cb(null, 'ok')
}
I have tried to use a callback function as the last argument in createGumballMachine() so that the machine is drawn first and then the gumballs are drawn afterwards, but this doesn't work.
I also tried using async and await but I coudn't get the image to render at all that way. Something was happening where vue could never get past the created portion of it's lifecycle.
I have tried reading about this on other SO questions, but I can't figure it out. I know it has something to do the way ctx.dtawImage() works, but I'm stuck.
Any help is appreciated. If you need to see the code for createGumballs() let me know, but I don't see how that is causing the problem.
Linking a relevant answer which also explains the inconsistent behavior. Essentially, you can use naturalWidth to ensure that the gumball machine has loaded.
https://stackoverflow.com/a/51023755/4409088

LexResponse output does not understand HTML data

I'm having a problem trying to get my AWS Lambda function to successfully output a series of HTML links when its running a SQL Query.
private string GetEventSearchResults(ILambdaContext context, List<Event> events, string CustomerNumber)
{
var result = string.Empty;
var link = string.Empty;
if (events.Count > 0)
{
result = $"Events for {CustomerNumber}:";
foreach (var evt in events)
{
link = "http://localhost/event/" + $"{evt.ID}";
result += $"<br>Event: {evt.ID} - Status: {evt.Status}";
}
}
else
{
result = "No Data found matching your query";
}
return result;
}
When this method is called by my Lambda function as a LexResponse,
replyMessage = GetEventSearchResults(context, eventList, query.CustomerNumber);
return Close(
sessionAttributes,
"Fulfilled",
new LexResponse.LexMessage
{
ContentType = "PlainText",
Content = replyMessage
}
);
This response is then rendered in my HTML page by a Javascript function. Relevant portion of the Javascript that renders the response:
function showResponse(lexResponse) {
var conversationDiv = document.getElementById('conversation');
var responsePara = document.createElement("P");
responsePara.className = 'lexResponse';
if (lexResponse.message) {
responsePara.appendChild(document.createTextNode(lexResponse.message));
responsePara.appendChild(document.createElement('br'));
}
if (lexResponse.dialogState === 'ReadyForFulfillment') {
responsePara.appendChild(document.createTextNode(
'Ready for fulfillment'));
// TODO: show slot values
}
conversationDiv.appendChild(responsePara);
conversationDiv.scrollTop = conversationDiv.scrollHeight;
}
However, the output shown by the Lex bot is as shown below:
Lex Bot Output
Can anyone please help me understand what exactly is going on? Is the content type of the Lex Response responsible for this? (there's only plaintext and SSML available for Lex Response so I can't change that)
Also, if possible, can anyone please explain how to fix this if at all possible? Thanks!
Your code is correct and output is also correct.
However the console window is not able to render the HTML part of your result.
The client on which you will deploy the chatbot, is responsible for rendering the output. For example, if you respond with a ResponseCard, console or website will not be able to render it correctly but it will be displayed correctly on Facebook and Slack. So, if you integrate your chatbot on some website it will show the links in your output correctly as you desired.
You can try to integrate your chatbot with Slack or Facebook first, to see the rendering of output.
Hope it helps.
After further trial and error, I managed to get a solution that works for me.
function showResponse(lexResponse) {
var conversationDiv = document.getElementById('conversation');
var responsePara = document.createElement("P");
responsePara.className = 'lexResponse';
if (lexResponse.message) {
var message = lexResponse.message.replace(/"/g, '\'');
responsePara.innerHTML = message;
responsePara.appendChild(document.createElement('br'));
}
conversationDiv.appendChild(responsePara);
conversationDiv.scrollTop = conversationDiv.scrollHeight;
}
By making the LexResponse an Inner HTML, it fixed the markup of the text and thus the link can be seen everytime.

Calculating total-items in AngularJs Pagination (ui.bootstrap) doesn't work correctly

I use controllerAs and avoid using the $scope as a model.
I want to add pagination in my search result. I have a paging object in my controller as below, which will be shared with angular service and then with the server API.
vm.paging = {
pageNumber: 1,
pageSize: 10,
totalCount: 0
};
totalCount will be set by server and then be read from response.
My pagination in html:
<pagination total-items="ctrl.pageCount"
items-per-page="ctrl.paging.pageSize"
ng-model="ctrl.paging.pageNumber"
class="pagination-sm"
boundary-links="true"
ng-change="ctrl.find()">
</pagination>
I calculate pageCount in controller as below:
vm.pageCount = function () {
return Math.ceil(vm.paging.totalCount / vm.paging.pageSize);
};
But it doesn't work. when I set vm.pageCount = 1000; it works. It seems the problem is the function. How can I fix this problem? (the buttons are disabled and It should return 100 pages, not one! )
Update: Sample Plunker
you CAN use an Immediately Invoked Function Expression (IFEE) to get your vm.pageCount like so
ctrl.pageCount = (function() {
return Math.ceil(ctrl.paging.totalItems / ctrl.paging.pageSize);
})();
but you don't need to calculate pageCount and put it under total-items (the amount of pages in the pagination will be calculated automatically), you should provide it the length of you record array instead!
lets say if you get table data vm.data from http, you should place the length of this data inside total-items like so
total-items="vm.data.length"
HTML
<uib-pagination total-items="ctrl.paging.totalItems"
items-per-page="ctrl.paging.pageSize"
ng-model="ctrl.paging.pageNumber"
class="pagination-sm"
boundary-links="true"
ng-change="ctrl.find()">
</uib-pagination>
JS
ctrl.paging = {
pageNumber: 1,
pageSize: 10,
totalItems: response.length // this is your remote data
};
I've made this plunker for you
EDIT 1
since version 0.14.0, the directives are prefixed by uib-
Since version 0.14.0 we started to prefix all our components. If you are upgrading from ui-bootstrap 0.13.4 or earlier, check our migration guide.
so you should also use uib-pagination (instead of pagination) because your plunk uses the 1.3.2 version.
I did it! Of course, with the guidance of my colleague :) . As in my plunk (script.js), I hadn't Initialized the vm.paging object after the response, so the computing was based on default values in vm.paging. Since totalCount was 0, always the Division result was 1 and I had just one page. So I edited the vm.find body as below:
vm.find = function () {
vm.result.length = 0;
vm.findingPromise = myService.find(vm.filter, vm.paging);
vm.findingPromise
.then(function (response) {
vm.result = response.data.result;
// EDITED PART:
vm.paging = response.data.paging;
//
}, function (response) {
var r = response;
ngNotify.set('Some problems occurred!',
{
type: 'error',
position: 'top',
sticky: true
});
});
And also, I couldn't take advantages of uib-pagination, but when I replaced ui-bootstrap-tpls-1.3.2.min.js anywhere I was using ui-bootstrap-tpls.min.js before, it works correctly.
Also I removed the function of computing pageCount. With many thanks to svarog.

multiple tinyMce instances not working in chrome

As with the title in Chrome (v.4.1) multiple tinyMce (v2.08) instances do not work. To be exact the first two instances are ok, the others not, and chrome gives this error:
Uncaught Error: INDEX_SIZE_ERR: DOM Exception 1
Has this happened before?
Unfortunately I can't show you any code because it's for an admin area, I just need some clue for the moment.
Yes, as user XP1 noted, at this link you can find resolution for a comprimed TinyMCE source:
http://my.opera.com/XP1/blog/2011/07/21/tinymce-javascript-error-in-opera-getrangeat-index-size-err
But if you want to work with original uncomprimed source (it's just a bit easier), here is the solution:
Look for code "setRng : function(r) {" (without quotes) and exchange the whole function with:
setRng : function(r) {
var s, t = this;
if (!t.tridentSel) {
s = t.getSel();
if (s) // this block fixed according to TinyMCE JavaScript error in Opera (getRangeAt, INDEX_SIZE_ERR); http://my.opera.com/XP1/blog/2011/07/21/tinymce-javascript-error-in-opera-getrangeat-index-size-err
{
if(s.anchorNode === null && s.focusNode === null)
{
t.explicitRange = r;
try {
s.removeAllRanges();
} catch (ex) {
// IE9 might throw errors here don't know why (NOW WE KNOW WHY DAMMIT!)
}
s.addRange(r);
}
if (s.rangeCount > 0)
t.selectedRange = s.getRangeAt(0);
}
} else {
// Is W3C Range
if (r.cloneRange) {
t.tridentSel.addRange(r);
return;
}
// Is IE specific range
try {
r.select();
} catch (ex) {
// Needed for some odd IE bug #1843306
}
}
},
ONE NOTE: please make sure variables match. I am not sure how it is between different TinyMCE versions BUT the variables are not the same between comprimed and src mutations of the script file.
Take Care and God Speed