Protractor can't find element by binding - protractor

I'm trying to find a element by binding, the problem is that the the element is an toast.
I'm using:
element(by.css('.btn-primary3')).click()
To simulate the click. As a result the toast does appear in the browser during the test.
Then I'm trying to store the element in a variable and test if the text value of the toast is equal to the expected value.
var toast = element(by.binding('toast.toast.title'));
expect(toast.getText()).toEqual('Inloggen mislukt');
But here the error pops up.
Failed: No element found using locator: by.binding("toast.toast.tile")
When I check the toast element in the the Chrome dev tools it shows up like this,
<div data-ng-repeat="toast in activeToasts">
<span data-ng-bind="toast.toast.title" class="ng-binding"> Inloggen mislukt</span>
</div>
I think the problem comes from the fact that that the span containing the binding doesn't exist on the dom when the page is loaded. It gets created when the button is clicked.

If this is the case, wait for the presence of the element after clicking the button:
element(by.css('.btn-primary3')).click();
var toast = element(by.binding('toast.toast.title'));
browser.wait(EC.presenceOf(toast), 5000);
expect(toast.getText()).toEqual('Inloggen mislukt');

May you should try:
<div data-ng-repeat="toast in activeToasts">
<span data-ng-bind="toast.toast.title" class="ng-binding"> Inloggen mislukt</span>
</div>

Related

"Clicking" on a not visible element

So my current situation is that I am trying to click on a marker based in a Google Maps window on a webpage. I have successfully located the markers in two manners: element.all(by.css('.angular-google-map-marker')) and element.all(by.repeater('m in map.markers')).
I have proven that I am obtaining the correct elements by changing the location on the Google Map and using count() to retrieve the number of markers present which returns the correct number in every case.
However, when I try to do for example element.all(by.css('.angular-google-map-marker')).first().click(), I receive the following error:
Failed: element not visible
HTML section
<div ng-transclude="" style="display: none">
<span class="angular-google-map-marker" ng-transclude="" ng-repeat="m in map.markers" options="m.options" coords="m.coords" idkey="m.id" click="onMarkerClick"></span>
<span class="angular-google-maps-window" ng-transclude="" coords="activeMarker.coords" options="windowMapOptions" show="windowMapOptions.show" closeclick="closeInfoWindow" templateurl="'gMapInfoWindow.html'" templateparameter="activeMarker"></span>
</div>
Normally elements that trigger some event due to clicking have an attribute like ng-click= foo(), however the markers above only use click= foo(). In addition if you look the line with the div tag, it says display: none, which might explain the visibility error.
My Question: Is there a way to activate the effect of an attribute like click= foo() without clicking on the element directly?
Aside from trying to make an element visible and then clicking, you can attempt clicking "via JavaScript" (there are some differences though - WebDriver click() vs JavaScript click()):
var marker = $('.angular-google-map-marker');
browser.executeScript("arguments[0].click();", marker.getWebElement());
First of all be sure that you can interact with the element when it is visible, you can do this from within the DevTools of your browser, make it visible by adding a display:block. Then check that if you change the value of the selectbox, the value can also be used with Angular Binding.
If so, you can easily make the element visible with Protractor by injecting a piece of Javascript in the page with the following command:
browser.executeScript('document.querySelector("div").style.display = "block"');
This results in a promise, so be aware of that!

Meteor: record in db updating, but data not changing on screen

Here's a simplified version of what I have in one of my templates:
{{#each dataRecord}}
{{#if editingNow}}
<tr class="dataRow">
<td><button class="updateRecord" id="{{this._id}}">SAV</button></td>
<td><input type="text" id="{{this._id}}" value="{{this.f}}"></td></td>
</tr>
{{else}}
<tr class="dataRow">
<td><button class="edit" id="{{this._id}}">EDIT</button></td>
<td>{{this.f}}</td>
<td><button class="deleteRecord" id="{{this._id}}">DEL</button> </td>
</tr>
{{/if}}
{{/each}}
editingNow returns the value of boolean session variable which starts out as false. So when the page loads, the user sees the value of the 'f' field for each record and the EDIT button. The EDIT button flips the session variable to true and then the data is shown using an input element. The user can edit the data and click the button, which is now a SAVE button. That button updates the record using the _id and flips the session variable back to false.
The works as far as editing the data goes -- the record is definitely getting updated. I can check the value in the console and see that it has been changed. But the data that gets displayed in the table reverts back to the original value. I can see the change displayed in that field very briefly and then it flips back. Even weirder, if I click the EDIT button again, the table still displays the old value. The only way to see the updated data in that field is to restart the app.
This problem never occurred when I was using my local mongo db or when I was linking to my database on meteor.com. This has only started happening since I moved my app to modulus.io. Any ideas?
UPDATE
Although I could not figure out what was causing the reactive update problem in the template, with Ethaan's help, I was able to get a better understanding of the issue and find a work-around, so I've accepted the answer and hopefully we will get to the bottom of this eventually.
Seems like you have some allow/deny problems maybe?
Try with
Collection.allow({
insert:function(){return true;},
remove:function(){return true;},
update:function(){return true;},
})
Or check the connection with the database is succefull, go to the admin panel on modulus
Option 2
Clean the database and make a dummy insert on the server side.
First on the meteor shell run meteor reset.
OR If you have the application is on modulus.io use the mongo shell, and use this piece of code.
db.getCollectionNames().forEach(function(name) {
if (name.indexOf('system.') === -1) {
db.getCollection(name).drop();
}
})
Now when you are sure the database is empty, put this on the server side.
//Server Code.
Meteor.startup(function(){
if(Collection.find().count() == 0){
Collection.insert({serverInsert:"test from server"},function(err,result){
if(!err){
console.log("insert succefull")
}
})
}
})

Casper.js/Phantom.js not submitting data

I'm using Casper.js to automate submitting a form. The form's onSubmit method returns false and runs some javascript (onclick callback) before sending the data, so I have to use clickLabel, instead of fill. The data is prepopulated, I just have to click the Submit button. When I use Casper to do clickLabel('Submit'), the data isn't submitted. What am I doing wrong?
Edit - here's the markup of the label:
<a class="green_btn white font_18 arrow_btn_pad rad_5" onclick="$.shactivity.eoiPremiumSubmit('expressval');return false;" href="javascript:void(0);">
<span class="fl cursor_p">Submit</span>
<span class="white_right_arrow mar_l_7 block fl mar_t_6 cursor_p"></span>
</a>
clickLabel invokes click in your case with the XPath selector of //*[text()='Submit']. click in turn will try dispatch mousefown and click events on the span with the Submit text. But the span won't have any such event handlers on it since this is what the parent link is for. The above XPath selector won't select the actual Link which is a parent of the span element.
You need to click the actual link to trigger the action:
casper.click(".green_btn.white.font_18.arrow_btn_pad.rad_5");
or with an XPath expression to select the parent based on the text:
var x = require('casper').selectXPath;
casper.click(x("//*[text()='Submit']/.."));

Using Watir with Chrome browser to find element on just opened web page

I try to find button on just opened page without sleep command.
HTML:
<span id="create-user-button" class="ui-button ui-widget ui-state-default
ui-corner-all ui-button-text-only" role="button" aria-disabled="false">
<span class="ui-button-text">Create‌·User</span>
</span>
Initialization of my element:
span(:create_user_button, :id => "create-user-button")
def open_user_creation_dialog
sleep 1
self.create_user_button_element.when_visible.click
end
When i use piece of code without sleep for Chrome browser, my page is closed and i can't find defined button. There isn't such problem for FF.
I try to use a lot of variants to fix it, like :
self.create_user_button_element.when_visible(2).click
self.create_user_button_element.when_present(2).click
Solution was found :
My page doesn't use Ajax, but there is very big table with users on my page, it takes a lot of time to download.
So i am waiting for download big table and after that i find very well my element.
My problem was solved.
div(:total_users_number, :id => "users-table_info")
def open_user_creation_dialog
self.wait_until(10, "No users displayed") do
self.total_users_number_element.when_visible.text != ""
end
self.create_user_button_element.when_visible.click
end
I have page with a very loadful content, namely list of users, so i should wait for element with big content. I do it, this way :
div(:total_users_number, :id => "users-table_info")
self.wait_until(10, "No users displayed") do
self.total_users_number_element.when_visible.text != ""
end
When this element loaded, i can find my sought element
self.create_user_button_element.when_visible.click

How to wait in watir-webdriver to load next page and then do assert on some random text

I am new to watir, and (believe me) I tried all the options that are avaliable here for adding wait and assert but have not been successful in doing so.
Here's a brief description of what I'm trying to do and appreciate your help.
I log into my website
I login using userid/password and hit click button.
I want watir to wait until next page is loaded
I want to do some assert to verify the login was successful.
My step 3 and step 4 are failing with the error element not found.
If I login manually and login is successful, I see text Hello,username at the top of the second page and this is what I've been trying to key off of but not having any success. It could be something very simple, but since I'm new to watir, I'm unable to figure it out.
Here are all the commands I tried:
$b.button(:id, 'usernameLogfaceinButton').click
#$b.wait_until($b.text.include?("Hello"))
#($b.text.include?("Hello")).wait_until_present
#$b.text_field(:text, "Hello").wait_until_present
if $b.text.include? "Hello"
puts "Test Passed. Found the test string: Hello- Actual Results match Expected Results."
else
puts "Test Failed! Could not find: Hello"
end
HTML on Page:
<body id="myAccounts" class="cardholderLayout ">
<div id="content">
<div id="navigationContainer">
<div id="headerNavigationMenu" class="innerContents">
<div class="logo"><img alt="xxx" src="/images/xxx.png?xxxxxxxx"></div>
<ul class="menu">
<li class="menuItem">
Hello, Bob
I hope someone can help me or point me in the right direction.
Try:
$b.link(:text => /^Hello/).wait_until_present
Notice that:
It is $b.link instead of $b.text_field. The method needs to match the type of element you are looking for.
The text in the locator is /^Hello/ instead of "Hello". If you pass a string (ie "Hello", watir will look for an element where the text exactly matches. If you want to do a partial text match, then you need to use a regular expression. The expression /^Hello/ says to find a text starting with "Hello".