Watin element finder error - watin

I am getting the below error when I try and find an element. My find method below.
public Element FindMenuItem(string menuItemName)
{
var menuItem = Element(Find.ByText(menuItemName));
var cells = ((ElementContainer<Element>)(menuItem)).TableCells;
return cells.Count > 0 ? cells.First() : menuItem;
}
The error:
WatiN.Core.Exceptions.WatiNException: It's not possible to find the element because no element finder is available.

This is a known bug with Watin, get the latest build and it should be fixed. Link to bug below.
http://sourceforge.net/p/watin/bugs/176/

Related

Kendo UI Fails to Bind ViewModel

I’m not sure just how much detail I can provide or how much is necessary here, but-
I’m trying to upgrade an application from Kendo UI v2015.1.429 to v2019.1.220. However, it is failing when I try to bind a particular viewmodel to an element, throwing Uncaught TypeError: Cannot read property 'length' of undefined.
I’ve managed to track what I believe is the cause of this bug to the inferSelect function, in the code below. However, as far as I can tell, everything involved is or should be defined and this error should not be happening. It's working perfectly fine for a viewmodel on another page, and it works if I remove one specific element that I'm trying to bind the viewmodel to, but I can't find any reason for that element to fail.
What further information should I provide/investigate to fix this?
function inferSelect(select, fields) {
select = $(select)[0];
var options = select.options;
var firstField = fields[0];
var secondField = fields[1];
var data = [];
var idx, length;
var optgroup;
var option;
var record;
var value;
for (idx = 0, length = options.length; idx < length; idx++) {
--> record = {}; //The error is thrown on this line
...........
PROBLEM SOLVED. I was trying to bind a multiselect widget to an <input> rather than to an actual <select>. Thanks Kendo for giving such an informative error message.

On sorting a jsp <select> element items vanishes

I have two listbox in a .jsp page with Add(+) and Remove(-) buttons in between. Two list boxes are 'Available Items' (left) and 'Selected Items'(right). 'Available Items' list box displays all the available items on page load fetching from DB, and 'Selected Items' listbox displays blank. User can add one item from left to right in 'Selected Items' listbox.
I have written code to move the items from both sides and vice versa. But the problem is when I am clicking 'Add' button to move the item from left to right, the item is moved properly to right listbox but the left list ('Available Items') items are getting vanished and reappears only after doing a click event the listbox which is weird from UI devlpment perspective. The same is happening for Remove button click. I hope there is some refresh issue underline. I am posting the codes below.
N.B : I have written a sort method to sort the items in the listbox. I troubleshooted that if I close calling the method sortItemsList() then everything is working fine.
Code for the listbox :
<tr>
<td>
<select id="leftItemList" size="8" multiple="multiple" style="height:auto"></select>
<input type="button" name="moveItemsToLeft" id="buttonAddItems" class="selectBoxAddButton checkboxDependent" value="Add >>" />
<input type="button" id="buttonRemoveItems" class="selectBoxRemoveButton checkboxDependent" value="<< Remove" />
<select id="rightItemList" size="8" multiple="multiple" style="height:auto"></select>
</td>
</tr>
Corresponding code for sort in javascript that is causing the issue :
Code for adding and removing items:
$('#buttonAddItems').click(function(){ //Moving items from left to right
var elementFrom = document.getElementById('leftItemList');
var element = document.getElementById('rightItemList');
var len = element.options.length;
var elementFromLength = elementFrom.length;
for ( var i = (elementFromLength - 1); i >= 0; i--) {
if ((elementFrom.options[i] != null) && (elementFrom.options[i].selected == true)) {
var selectedItemLength = $("#leftItemList :selected").length;
element.options[len] = new Option(
elementFrom.options[i].text,
elementFrom.options[i].value);
len++;
elementFrom.options[i] = null;
}
}
sortItemsList(); //Commenting this call fixes the problem
});
$('#buttonRemoveItems').click(function(){ //Moving items from right to left
var element = document.getElementById('rightItemList');
var elementTo = document.getElementById('leftItemList');
var len = element.options.length;
var elementFromLength = elementTo.length;
for ( var i = (len - 1); i >= 0; i--) {
if ((element.options[i] != null) && (element.options[i].selected == true)) {
elementTo.options[elementFromLength] = new Option(
element.options[i].text,
element.options[i].value);
elementFromLength++;
element.options[i] = null;
}
}
sortItemsList(); //Commenting this call fixes the problem
});
function sortItemsList(){
var options = $("#leftItemList option"); // Collect options
options.detach().sort(function(a,b) { // Detach from select, then Sort
var at = $(a).text();
var bt = $(b).text();
return (at > bt)?1:((at < bt)?-1:0); // Tell the sort function how to order
});
options.appendTo("#leftItemList");
}
N.B : The code for sorting that I used is taken from reference whose URL is below. Have tried both Approaches. None of them is working. I do have same '3.4.1/jquery.min.js' as in reference -
https://www.geeksforgeeks.org/how-to-sort-option-elements-alphabetically-using-jquery/
#Swati I am having the same problem running your code in jsfiddle (which you are running successfully). So the problem is with Chrome version. My chrome version is 'Version 81.0.4044.113 (Official Build) (64-bit)'. I guess yours is 'Chrome version 80.0.3987.122' one version older than me with which it is working fine. Finally the observations are as below.
Observations
In the higher chrome version, the code is working fine till sorting. But when the code is trying to append the sorted itemList into existing itemList object, there was some issues with DOM manipulation with latest chrome version against appendTo() method, which means appendTo() method is adding sorted itemList into existing DOM element but refresh or reload is not happening with that DOM element. That's why the vanished itemList drop down is getting all the values after a mouse click event on the drop down manually.
In order to fix this issue, we need to do manual refresh. We can do the refresh or reload by two different ways as mentioned below.
Approach 1 :
Adding the below line after itemList append.
$("#leftItemList").html($("#leftItemList").html());
Approach 2 :
We can set the focus on leftItemList element after append. If we follow this approach, when we click Add button it will add the item list to right side but the focus will be there is the leftItemList drop down.
$("#leftItemList").focus();
So Approach 1 is the preferable solution.

Selenium "Element is not clickable at point" error in Firefox

In regards to the Webdriver error
Element is not clickable at point (X, Y). Another element would recieve the click instead.
For ChromeDriver, this is addressed at Debugging "Element is not clickable at point" error, however the issue can occur in Firefox as well.
What are the best ways to resolve this when it occurs in FirefoxDriver?
This happens in the below cases-
When the element is loaded into the DOM, but the position is not
fixed on the UI. There can be some other div or images that are not
loaded completely.
The page is getting refreshed before it is clicking the element.
Workaround
Use Thread.sleep before actions on each web element in UI, but it is
not a good idea.
Use WebDriverWait ExpectedConditions.
I was facing the same issue, the page load time was more and a loading icon was overlapping on entire web page.
To fix it, I have implemented WebDriverWait ExpectedConditions, which waits for the loading icon to disappear before performing click action on an element
Call this function before performing an action (I am using data driven framework)
public void waitForLoader () throws Exception {
try {
String ObjectArray[]=ObjectReader.getObjectArray("LoadingIcon");
if(checkElementDisplayed(ObjectArray[3],ObjectArray[2]))
{
WebDriverWait wait = new WebDriverWait(remotewebdriver,10);
wait.until(ExpectedConditions.invisibilityOfElementLocated(By.xpath(ObjectArray[3])));
}
} catch (NoSuchElementException e) {
System.out.println("The page is loaded successfully");
}
}
If your problem is that the element is scrolled off the screen (and as a result under something like a header bar), you can try scrolling it back into view like this:
private void scrollToElementAndClick(WebElement element) {
int yScrollPosition = element.getLocation().getY();
js.executeScript("window.scroll(0, " + yScrollPosition + ");");
element.click(); }
if you need you could also add in a static offset (if for example you have a page header that is 200px high and always displayed):
public static final int HEADER_OFFSET = 200;
private void scrollToElementAndClick(WebElement element) {
int yScrollPosition = element.getLocation().getY() - HEADER-OFFSET;
js.executeScript("window.scroll(0, " + yScrollPosition + ");");
element.click();
}
You can direct click using JavascriptExecutor (Not recommanded)
WebElement element= driver.findElement(By."Your Locator"));
JavascriptExecutor executor = (JavascriptExecutor) driver;
executor.executeScript("arguments[0].click();", element);
Hope it will help you :)
My same problem is solved by Javascript, Please try following code instead of selenium click
WebElement rateElement = driver.findElement(By.xpath(xpathContenRatingTab));
((JavascriptExecutor)driver).executeScript("arguments[0].click();", rateElement);
Careful matching of the Selenium jar version with the Firefox version can fix the issue. Selenium should automatically scroll an element into view if it isn't on the page. Forcing an element into view with JavaScript is unnecessary.
We never see this issue in Firefox 31.5.0 with selenium-server-standalone-2.44.0.jar, however when upgrading to Firefox 38.7.0 with selenium-server-standalone-2.52.0.jar, it became an issue.
See https://github.com/seleniumhq/selenium/issues/1543
I had the same problem and I solved it using certain capability. While you are using FirefoxDriver, you can set "overlappingCheckDisabled" to true to solve your problem.
capabilities.setCapability("overlappingCheckDisabled", true);
ActionBuilder can resolve the error. Sometimes there is another element in front of the object that needs to be clicked, so an ActionBuilder click to the location of the element may work in cases where a traditional click fails
Actions actions = new Actions(driver);
actions.moveToElement(clickElement).click().perform();
or try the middle of the element
Actions actions = new Actions(driver);
Integer iBottom = clickElement.getSize().height;
Integer iRight = clickElement.getSize().width;
actions.moveToElement(clickElement, iRight/2, iBottom/2).click().perform();
This Error coud ocur when for example u make to many accesses to some service , for example if u are making as I a bot .... For example instagram will block u for some period if u ar taged as blocked and then that error coud ocour not allowing u to click some elements in the page.
Try make another acount and switch to a vpn becouse probably your ip is already marked as blocked
Try to maximize the browser when you are working with resolutions greater than 1024x768. It works for me in js.
driver.manage().window().maximize();

how does Jasmine 'expect' waits for a protractor promise to resolve

I'm working on e2e testing.
I have a confirm pop which doesnt exist on the page till I click a button.
Once the confirm popup is create I get the text from an element there.
After that I click on OK button which causes the confirm popup to be delete from the DOM and also add a new element to the DOM with the value i got the text earlier.
the problem is, because getText() returns a promise, by the time I do the comparison the first element is not present on the screen and the test fails.
if I do expect while the confirm popup on the screen I can see the text of the confirm popup element.
how does Jasmine expect() resolve the promise?
thanks in advance
Something like this?
element(by.id('dangerous-activity')).click().then(function () {
element(by.id('confirmation-text')).getText().then(function (textToConfirm) {
element(by.id('confirm-button')).click().then(function () {
element(by.id('new-element')).getText().then(function (newText)) {
expect(newText).toBe(textToConfirm);
});
});
});
});
Here all promises are explicitly resolved, so Jasmine does not need to resolve any promise anymore.
You can let expect resolve the new-element promise, replacing the last two lines by:
....
expect(element(by.id('new-element')).getText()).toBe(textToConfirm);
....
But you cannot get the textToConfirm in the same expectation, since it is gone by then as you indicated.
This should be the simplest way to do what you want:
$('#open-popup').click();
var textToConfirm = $('#popup-text').getText();
$('#confirm-button').click();
var newText = $('#new-element').getText();
expect(newText).toBe(textToConfirm);
Note this will not work:
$('#open-popup').click();
var textToConfirmElement = $('#popup-text');
$('#confirm-button').click();
var newText = $('#new-element').getText();
expect(newText).toBe(textToConfirmElement.getText());
because here you get the text after the popup is already closed.

Kendo Grid - PopUp windows not being removed from the DOM

I have a kendo grid with a custom popup:
columns.Command(commands =>
{
commands.Edit();
}
.Editable(editing => editing.Mode(Kendo.Mvc.UI.GridEditMode.PopUp))
Each time I click the edit button the window pops up but when I close it the window is not removed from the DOM.
I saw this post: http://www.telerik.com/forums/popup-windows-do-not-get-removed-from-dom and Telerik says the issue has been fixed.
What are some things that would cause this behavior?
UPDATED
This grid is nested in a Kendo TabStrip if that helps. Other than that I don't see anything out of the ordinary. The popup is entirely managed by the grid.
UPDATED 2
So I got the un-minimized code for the grid (kendo.grid.min.js, version 2013.3.1119, starting at line 1172), slopped it into my project and modified just the following with the two log statements to verify that destroy is being bound and called:
_destroyEditable: function () {
var that = this;
var destroy = function () {
if (that.editable) {
// My edit
console.log("...destroy() called");
that._detachModelChange();
that.editable.destroy();
that.editable = null;
that._editContainer = null;
}
};
if (that.editable) {
if (that._editMode() === "popup") {
// My edit
console.log("Binding destroy() to 'deactivate'...");
that._editContainer.data("kendoWindow").bind("deactivate", destroy).close();
} else {
destroy();
}
}
},
Each time I click edit and then close the window I see the expected two messages yet the window is not removed. Here is a screenshot of the debugger:
The outlined windows are the dom elements generated.
After much trial and error and deep diving it turns out this problem has to do with our scripts in our site's layout. At some point whomever setup the kendo scripts put in not only the 'kendo.all.min.js' but right after it 'kendo.web.min.js', 'kendo.aspnetmvc.min.js' and then about 10 individual kendo.*.js including the grid.
After viewing this link:
http://docs.telerik.com/kendo-ui/getting-started/javascript-dependencies
I realized that the site is creating these objects multiple times. Removing the script references in accordance to the link above resolves the issue.

Resources