Geb: Getting value from dropdown datalist (Element not visible error) - geb

I need to select an option from a datalist which gets populated after a short time duration. This is what I have tried-unsuccessfully- so far.
Module module.groovy
inputBox { $("input", 0) }
clientListItemOne{ $("datalist option", 0) }
clientListItemTwo { $("datalist option", 3) }
clientListItemThree { $("datalist option", 7) }
UI Test
try{
module.inputBox.click().click()
waitFor("quick") { module.clientListItemOne.displayed }
module.clientListItemOne.click()
}
The result is that even though the dropdown datalist is visible, the browser gets stuck in the waitFor loop and quits.
Without using the waitFor loop, I get an 'element not visible' error.
How do I remedy this situation?
Thanks a lot in advance.

Related

protractor + cucumber - element not visible even though element is visible

this.When(/^the user clicks on login button$/, function () {
return browser.wait(wagLoginPage.loginPage.signIn.isPresent().then(function (visible) {
if(visible){
console.log("element is visible !!!!!!!");
wagLoginPage.loginPage.signIn.click().then(function(){
expect(visible).to.be.true;
});
}
else{
expect(visible).to.be.true;
}
}, function () { chai.assert.isFalse(true, "SingIn is not visible!") }));
});
My test randomly fails in the above step. For the above code, in console window protractor prints 'element is visible'. But if I perform click event on the element it throws element is not visible exception.
Update
Questions is answered here
Your element is present, but it's probably not visible.
Try this:
return browser.wait(wagLoginPage.loginPage.signIn.isDisplayed().then(function (visible){
//Your stuff
}
Note, I'm using isDisplayed() vs. isPresent().
isPresent() is useful if you are checking if an element is on the page, but may or may not be visible.
isDisplayed() is useful if you are checking if an element is visible on the page.

How to continue webdriver/selenium after error

I'm doing a test bot with webdriver. I have a scenario where it clicks on a button, a new windows open, and it searches for an element by a specific xpath, but sometimes there is no such element because it can be disabled and i get this error: org.openqa.selenium.NoSuchElementException. How can i bypass it/continue the bot so it just closes the new windows if it doesn't find the element with that xpath and just continue with the code?
In Java :
List<WebElement> foundElement = driver.findElements(By.xpath("<x-path of your element>"));
if (foundElement.size() > 0)
{
// do whatever you want to do in **presence** of element
} else {
// do whatever you want to do in **absence** of element
}
You need to surround the click event with a try/catch statement, and inside the catch statement check if the exception is the one you are trying to bypass:
try {
driver.findElement(by).click();
} catch(Exception e) {
if ( !(e instanceof NoSuchElementException) ) {
throw e;
}
}

How do I display invalid form Dijits inside closed TitlePanes?

I have a large Dijit-based form with many Dijits in collapsible TitlePanes.
When the form validates, any invalid items hidden inside closed TitlePanes (obviously) cannot be seen. So it appears as though the form is just dead and won't submit, though, unbeknownst to the user, there's actually an error hidden in a closed TitlePane which is preventing the form processing.
What's the solution here? Is there an easy way to simply open all TitlePanes containing Dijits that are in an error state?
If validation is done by following, it will work:-
function validateForm() {
var myform = dijit.byId("myform");
myform.connectChildren();
var isValid = myform.validate();
var errorFields = dojo.query(".dijitError");
errorFields.forEach(fieldnode){
var titlePane = getParentTitlePane(fieldnode);
//write a method getParentTitlePane to find the pane to which this field belongs
if(titlePane) {
titlePane.set('open',true);
}
}
return isValid;
}
function getParentTitlePane(fieldnode) {
var titlePane;
//dijitTitlePane is the class of TitlePane widget
while(fieldnode && fieldnode.className!="dijitTitlePane") {
fieldnode= fieldnode.parentNode;
}
if(fieldnode) {
mynode = dijit.getEnclosingWidget(fieldnode);
}
return titlePane;
}
Lets say if the following is the HTML and we call the above validateForm on submit of form.
<form id="myform" data-dojo-type="dijit/form/Form" onSubmit="validateForm();">
......
</form>
Here's what I ended up doing (I'm not great with Javascript, so this might sucked, but it works -- suggestions for improvement are appreciated):
function openTitlePanes(form) {
// Iterate through the child widgets of the form
dijit.registry.findWidgets(document.getElementById(form.id)).forEach(function(item) {
// Is this a title pane?
if (item.baseClass == 'dijitTitlePane') {
// Iterate the children of this title pane
dijit.registry.findWidgets(document.getElementById(item.id)).forEach(function(child) {
// Does this child have a validator, and -- if so -- is it valid?
if (!(typeof child.isValid === 'undefined') && !child.isValid()) {
// It's not valid, make sure the title pane is open
item.set('open', true);
}
});
}
});
}

Select a hidden element with PHPunit

Is it possible to locate an element altho it is hidden? I want a function that looks for my tooltip that says something was not filled correctly in my form.
the function looks like this:
public function checkTooltip()
{
$element = $this->byClassName('tooltip');
if ($element->displayed())
{
echo "something was not filled correctly";
}
}
$var1->value('hello');
$this->checkTooltip();
$var2->value('world');
$this->checkTooltip();
$var3->value('!');
$this->checkTooltip();
This works perfectly when the tooltip appears but if there is nothing wrong I get the message:
"PHPUnit_Extensions_Selenium2TestCase_WebDriverException: no such element"
And this make sence because it's hidden when nothing is going wrong but I want to select that element anyways, becouse I want my test to make sure that it's not vissible during my test to make sure everything is okey.So is there a way to select a hidden element using phpunit_Selenium2TestCase?
This worked as a charm!
public function checkError()
{
$tooltip = $this->elements($this->using('css selector')->value('div.active div.invalid'));
if(count($tooltip) != 0)
{
foreach ($tooltip as $tool)
{
$warning = $tool->text();
echo "You got a invalid tooltip with this message '".$warning."'";
}
}
}

WinJS Listview shows undefined when navigating quickly

I have a WinJS application with listviews in which if quickly navigate between pages before the listview is fully loaded, the next page shows the listview with all elements in it bound as "undefined".
So say I have a hub page with a "to do" that is filtered to only show 6 items, and there is a header that navigates to the full "to do" page, when the hub page is displayed but before it is fully loaded I click on the header link to the "to do" page, the app then goes to the "to do" page, but the items show up with all the properties in the tile as "undefined".
I am using IndexedDB as my data store.
My home page code looks like this:
WinJS.UI.Pages.define("/pages/home/home.html", {
ready: function (element, options) {
WinJS.Utilities.query("a").listen("click", function (e) {
e.preventDefault();
WinJS.Navigation.navigate(e.currentTarget.href);
}, false);
viewModel = new HomeViewModel(element);
viewModel.load(); //loads from indexed db
},
//etc...
To Do Page:
WinJS.UI.Pages.define("/pages/ToDo/ToDo.html", {
ready: function (element, options) {
viewModel = new ToDoViewModel(element);
viewModel.load();
},
etc//
I know there isn't much to go off, but any ideas would be appreciated.
Also tips on how to debug something like this would be great.
Update
I narrowed it down to this one line from the Hub Page:
myLib.GetData(todaysDate, function (result) {
that.trendsModel.today = result;
WinJS.Binding.processAll(that.el.querySelector("#dataPanel"), that.trendsModel); //<--Right Here
});
If I remove that, then when I load the second page the data doesn't show as undefined. What is interesting is the data initially shows correctly on the second page and then it changes to "undefined".
Solution
My fix:
myLib.GetData(todaysDate, function (result) {
var element = that.el.querySelector("#dataPanel");
that.trendsModel.today = result;
if(element) {
WinJS.Binding.processAll(element, that.trendsModel);
}
});
At the point when when the callback returns, I am already on the second page. So the selector was not found returning null. If you pass null to processAll it tries to bind the whole page which is why I was able to see the correct data for a second then it changes to undefined...Wow, what a doozy. I guess it makes sense but what a pain to find.
Hope it helps someone in the future :)
Your ToDoViewModel, and HomeViewModel need to be observable. This means they need to mix in from WinJS.Binding.mixin, and for the properties that you pull in asynchronously, they need to call this.notify("propertyName", newVal, oldVal) from the property setter.
Note that you need to have getter/setter properties. e.g.
var bindingBase = WinJS.Class.mix(function() {}, WinJS.Binding.mixin);
WinJS.Namespace.define("YourNamespace", {
ToDoViewModel: WinJS.Class.derive(bindingBase, function constructor() {
}, {
_titleStorage: "",
title: {
get: function() { return this._titleStorage; },
set: function(newValue) {
if(newValue === this._titleStorage) {
return;
}
var old = this._titleStorage;
this._titleStorage = newValue;
this.notify("title", newValue, old);
}
}
}),
});
myLib.GetData(todaysDate, function (result) {
var element = that.el.querySelector("#dataPanel");
that.trendsModel.today = result;
if(element) {
WinJS.Binding.processAll(element, that.trendsModel);
}
});
At the point when when the callback returns, I am already on the second page. So the selector was not found returning null. If you pass null to processAll it tries to bind the whole page which is why I was able to see the correct data for a second then it change to undefined...Wow, what doozy. I guess it makes sense but what a pain to find.