Caused by: org.openqa.selenium.InvalidSelectorException: - selenium

I am new in Selenium automation testing
Getting Selenium Error
When I am trying to run below code every time I got error"org.openqa.selenium.TimeoutException: Expected condition failed: waiting for visibility of element located by By.xpath" I am not sure what xpate will be could some one please help me
Created Automation test case for Login Application.
Java:
#Test
public void enterApplicationCerdentials(String userName, String password) {
WebDriverWait wait = new WebDriverWait(driver, 50);
wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//frameset/frame/html/body/div([#class='tintedBox' and #id='loginBox']/table/tbody/tr/td/input[#id='UserID' and name='UserID'])"))).sendKeys(userName);
wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("Password"))).sendKeys("CSRWHKXESB");
captureScreen();
}
HTML:
<frameset rows="*, 1">
<frame src="Script/Login.asp?">
#document
<!--Function return the password for the user who logged in through Referral URL.
For TAFE user password is not matching as per database value as their URL is dynamic. ENHC0014091
This function splits the URL of that particular user (8527066229) only . -->
<html><head>
<script language="JavaScript">
//<!--
function OnLoad()
{
setTimeout("CheckFrame()", 4000);
}
function CheckFrame()
{
with (parent)
{
if ((length==0 && document.frmCheck==null) ||
(length>0 && frames[1].document.frmCheck==null))
{
var PathName = window.location.pathname;
PathName = PathName.substr(0, PathName.substr(1).indexOf("/") + 1);
location.href = PathName;
}
}
}
//-->
</script></head>
<body onload="OnLoad()" topmargin="0" leftmargin="0" bgcolor="#ffffff" text="#000000" link="#000000" vlink="#000000" alink="#000000">
<div id="login">
<img border="0" src= vspace="10" style="display: block;">
<div class="tintedBox" id="InfoStoreBox">
<h1> <a class="boldLink" href="https://infostore.saiglobal.com" target="_parent"><u>InfoStore</u></a> ?</h1>
<p></p>
<p><a class="boldLink" href="https://infostore.saiglobal.com" target="_parent"></a> .</p>
<p>Not only a shop, <a class="boldLink" href="https://infostore.saiglobal.com" target="_parent"></a> </p>
<p></p>
</div>
<div class="tintedBox" id="loginBox">
<h1></h1>
<form name="form" action="Login.asp?" method="post">
<input type="hidden" name="Autologout" value="false">
<input type="hidden" name="Division" value="">
<span class="error"></span>
<table>
<tbody><tr>
<td>User ID</td>
<td><input type="text" size="30" id="UserID" name="UserID" value=""></td>
</tr>
<tr>
<td>Password</td>
<td><input type="password" size="30" id="Password" name="Password" value=""></td>
</tr>
<tr>
<td>Last Name/Location</td>
<td><input type="text" size="30" id="UserName" name="UserName" value=""></td>
</tr>
</tbody></table>
<br>
<font color="#d12b2c"><nobr>Your Last Name and Location are now mandatory to access the platform, simply</nobr><br>enter the details in field (e.g. Smith/Perth)</font>
<br><br>
<div>
<input type="checkbox" id="SaveLogin" name="SaveLogin" value="SaveLogin"><label for="SaveLogin" id="save">Save my login so you can remember me on my next visit.</label>
</div>
<div align="center" style="padding-top:20px">
<input class="button" type="submit" name="Submit" value="Submit">
<input class="button" type="reset" name="Clear" value="Clear">
<input class="button" type="submit" name="Recognize" value="Remember me?">
</div>
<div style="padding-top:20px">
<nobr>Lost password? Contact your internal Administrator or <a class="boldLink" href="mailto:sales#saiglobal.com?subject=Lost SOL password">our Customer Service</a></nobr>
</div>
</form>
</div>
</div>
<div id="footer" onmouseover="ShowTime()">©2014 SAI Global</div>
<script>
function ShowTime()
{
var spTime = document.getElementById("footer");
spTime.innerHTML = "©2014 SAI Global - 20190426 12:25:33.292: 172.20.33.12, 203.27.21.6, 59596377";
}
</script>
</body></html>
Error:
org.openqa.selenium.TimeoutException: Expected condition failed:
waiting for visibility of element located by By.xpath:
//frameset/frame/html/body/div([#class='tintedBox' and
#id='loginBox']/table/tbody/tr/td/input[#id='UserID' and
name='UserID']) (tried for 50 second(s) with 500 milliseconds
interval)
at org.openqa.selenium.support.ui.WebDriverWait.timeoutException(WebDriverWait.java:95)
at org.openqa.selenium.support.ui.FluentWait.until(FluentWait.java:272)
at seleniumPages.Page_LoginMyApplication.enterApplicationCerdentials(Page_LoginMyApplication.java:67)
at stepDefinitions.StepDefs_DataDrivenLogin.i_login_with_credentials_and(StepDefs_DataDrivenLogin.java:23)
at ?.I login with credentials "tomsmith" and "***************"(resources/features/DataDrivenLogin.feature:7) Caused
by: org.openqa.selenium.InvalidSelectorException: invalid selector:
Unable to locate an element with the xpath expression
//frameset/frame/html/body/div([#class='tintedBox' and
#id='loginBox']/table/tbody/tr/td/input[#id='UserID' and
name='UserID']) because of the following error: SyntaxError: Failed to
execute 'evaluate' on 'Document': The string
'//frameset/frame/html/body/div([#class='tintedBox' and
#id='loginBox']/table/tbody/tr/td/input[#id='UserID' and
name='UserID'])' is not a valid XPath expression. (Session info:
chrome=73.0.3683.103) (Driver info: chromedriver=2.46.628402
(536cd7adbad73a3783fdc2cab92ab2ba7ec361e1),platform=Windows NT
6.3.9600 x86_64) (WARNING: The server did not provide any stacktrace information) Command duration or timeout: 0 milliseconds For
documentation on this error, please visit:
https://www.seleniumhq.org/exceptions/invalid_selector_exception.html
Build info: version: '3.141.59', revision: 'e82be7d358', time:
'2018-11-14T08:25:48' System info: host: 'AP01154W8N', ip:
'192.168.56.1', os.name: 'Windows 8.1', os.arch: 'amd64', os.version:
'6.3', java.version: '1.8.0_191' Driver info:
org.openqa.selenium.chrome.ChromeDriver Capabilities
{acceptInsecureCerts: false, acceptSslCerts: false,
applicationCacheEnabled: false, browserConnectionEnabled: false,
browserName: chrome, chrome: {chromedriverVersion: 2.46.628402
(536cd7adbad73a..., userDataDir: C:\Users\sinham0\AppData\Lo...},
cssSelectorsEnabled: true, databaseEnabled: false, goog:chromeOptions:
{debuggerAddress: localhost:65139}, handlesAlerts: true,
hasTouchScreen: false, javascriptEnabled: true,
locationContextEnabled: true, mobileEmulationEnabled: false,
nativeEvents: true, networkConnectionEnabled: false, pageLoadStrategy:
normal, platform: XP, platformName: XP, proxy: Proxy(), rotatable:
false, setWindowRect: true, strictFileInteractability: false,
takesHeapSnapshot: true, takesScreenshot: true, timeouts: {implicit:
0, pageLoad: 300000, script: 30000}, unexpectedAlertBehaviour: ignore,
unhandledPromptBehavior: ignore, version: 73.0.3683.103,
webStorageEnabled: true} Session ID: 869efd2308887ee98e8d561566b5a606
*** Element info: {Using=xpath, value=//frameset/frame/html/body/div([#class='tintedBox' and
#id='loginBox']/table/tbody/tr/td/input[#id='UserID' and
name='UserID'])}
at sun.reflect.GeneratedConstructorAccessor10.newInstance(Unknown Source)

The reason you are getting TimeoutException is that the element you are finding is in a frame and you have to switch to that frame. Otherwise, webdriver can't find the element.
First, find the appropriate selector for the frame tag. According to your provided HTML I'm constructing the locator.
XPath:
WebElement loginFrame = driver.findElement(By.xpath("//frameset/frame[#src='Script/Login.asp?']"));
CSS Selector:
WebElement loginFrame = driver.findElement(By.cssSelector("frameset > frame[src='frame_c.htm']"));
Try this:
#Test
public void enterApplicationCerdentials(String userName, String password) {
WebDriverWait wait = new WebDriverWait(driver, 50);
By frameLocator = By.xpath("//frameset/frame[#src='Script/Login.asp?']");
wait.until(ExpectedConditions.presenceOfElementLocated(By.xpath("//frameset/frame[#src='Script/Login.asp?']")));
driver.switchTo().frame(driver.findElement(frameLocator));
wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("UserName"))).sendKeys("UserName");
wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("Password"))).sendKeys("Password");
captureScreen();
}

Related

Toast Notifications not appearing after handler execution

I'm using NToastNotify V6.1.3 in a .NET Core 3.1 application.
Problem
I had a modal (in a ViewComponent) where I inserted data throughout a controller's handler/action. This would refresh the page with the new updated data and give the user a toast notification. Now my requirements change and I wish to keep the modal open and allow the user to input multiple records before deciding to close up the modal and only then refresh the page. To do this I changed my handler return from return LocalRedirect("/Account/Production/Index"); to return NoContent();.
This works to a certain extent... The problem I have is that all the toast notifications will only show up when the user finally makes an action that refreshes the page, and not once every time the handler gets called.
Question
How to show the toast notifications as soon as my handler succeeds, and without the need to refresh the page?
Controller Handler
[HttpPost]
public async Task<IActionResult> InsertLabelDefectRobotsT(DefectModalViewModel model)
{
...
_toastNotification.AddSuccessToastMessage(model.Quantity + " peca(s) com defeito adicionada(s).");
return NoContent(); //NOW
//return LocalRedirect("/Account/Production/Index"); BEFORE
}
ViewComponent
<div class="modal fade" id="modalDefectsRobots" tabindex="-1" role="dialog" aria-labelledby="modalDefectsRobots" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header bg-danger">
<h5 class="modal-title" id="modalDefectsRobots">
<i class="fas fa-thumbs-down mr-2"></i>Inserção de Defeitos
</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<div id="modalDefectsLoader" class="text-center" style="display:none;">
<img src="~/images/svg/ajax-loader.svg" />
</div>
<alert type="Warning">
Todos os defeitos serão registados para a célula escolhida.
</alert>
<form id="formDefectsRobots" method="post" asp-action="InsertLabelDefectRobotsT" asp-controller="Labels" onsubmit="onSubmit(this)">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
...
...
...
<div class="row mb-3">
<div class="col-md-12">
<button type="button" class="btn btn-dark" data-dismiss="modal"><i class="fas fa-arrow-left mr-2"></i>Cancelar</button>
<button type="button" class="btn btn-success" onclick="doSomething();submitDefectsRobots(this)"><i class="fas fa-play-circle mr-2"></i>Introduzir Defeito</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
JS Call Handler On Submit
function submitDefectsRobots(button) {
$form = $('#formDefectsRobots');
if ($form.valid()) {
Swal.fire({
title: "Inserir Defeito?",
text: "Esta acção irá inserir um novo registo de defeito.",
type: 'warning',
showCancelButton: true,
confirmButtonColor: '#3085d6',
cancelButtonColor: '#d33',
cancelButtonText: 'Cancelar',
confirmButtonText: 'Confirmar',
animation: false,
focusCancel: true
}).then((willSubmit) => {
if (willSubmit.value) {
$form.submit();
hideOverlay();
}
})
}
}
I ended up solving this by changing the toast call from the handler to the javascript file:
function submitDefectsRobots(button) {
$form = $('#formDefectsRobots');
if ($form.valid()) {
Swal.fire({
title: "Inserir Defeito?",
text: "Esta acção irá inserir um novo registo de defeito.",
type: 'warning',
showCancelButton: true,
confirmButtonColor: '#3085d6',
cancelButtonColor: '#d33',
cancelButtonText: 'Cancelar',
confirmButtonText: 'Confirmar',
animation: false,
focusCancel: true
}).then((willSubmit) => {
if (willSubmit.value) {
$form.submit();
hideOverlay();
setTimeout(function () {
toastr.success("Defeitos Inseridos");
$('.defectsSelect').val('0');
}, 1000);
}
})
}
}
While this is not perfect since I'm calling it after the form submission regardless of the response (I would need AJAX for waiting for the response), it is a workaround for now since I refresh the page in an error case.

ion range slider and modal: how to populate to and from before modal is shown

I am using ionrangeslider in a modal
<!-- The Modal -->
<div class="modal" id="myModal">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content" style="width: auto;margin: 0 auto">
<!-- Modal body -->
<div class="modal-body">
<input type="text" id="mySlider"/>
</div>
</div>
</div>
</div>
I get some values from ajax and after that i set the to and from for the slider like
$(document).ready(function () {
$('#mySlider').ionRangeSlider({
grid: false,
type: 'double',
min: 1,
max: 10,
force_edges: true,
drag_interval: true,
step: 1,
});
$.ajax({
url: "/get_schedule_for_zone/",
type: 'POST',
headers: { 'X-CSRFToken': csrftoken },
data: {"deviceassigned_id": parseInt(deviceassigned_id),"zone_number": parseInt(zone_number)},
success: function(res) {
$('#mySlider').data("ionRangeSlider").update({from: res.to})
$('#mySlider').data("ionRangeSlider").update({to: res.from})
$('$myModal').modal('show')
},
error : function(xhr,errmsg,err) {
console.log(err)
}
})
})
what i found it the modal open and then shows the slider without to and from, and then updated the to and from. the user can see that they are changing from nothing to some values
how to set them before i open the modal and show them there.
if your slider is inside a div, just hide it:
<div id="slider">
<input type="text" class="js-range-slider" id="test" name="my_range" value=""
data-min="40"
data-max="210"
data-from="{{row2.7}}"
data-grid="true"
data-hide-min-max="true"
data-postfix="'F"
data-type="double"
/>
</div>
$("#slider").hide();
and after displaying you modal, (or just before)
$("#slider").show();
other solution is to play with opacity

Selenium says element is not visible when it is with latest Firefox (ElementNotInteractableException: Element is not visible)

On our test page we have a username field and a password field as follows:
<input required="" placeholder="USERNAME" id="usernameIdentification"
class="form-control no-upper-case autoExpand textValidation"
autofocus="autofocus" autocapitalize="none" autocorrect="off"
spellcheck="false" size="20" type="text">
<input id="password" name="password" placeholder="PASSWORD" class="form-
control no-upper-case autoExpand textValidation" required="required"
autofocus="" autocomplete="password" autocapitalize="none"
autocorrect="off" spellcheck="false" type="password" hidden="true">
The username field is filled out by selenium, we hit a next button and the next page has the password field.
Using: Firefox version 46.0.1 and Selenium version 2.53.1
The following code was working fine:
//Enter username
WebElement userField = wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("usernameIdentification")));
userField.sendkeys(username);
//Press next button
wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("nextButton"))).click();
//Fill password
WebElement passwordField = wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("password")));
passwordField.sendKeys(password);
When I update to: Firefox version 57, and selenium 3.7.1, with geckodriver 0.19.1
The code breaks, selenium will not enter text into the password field anymore, I can manually enter the password without issue, but selenium keeps insisting that the field is not visible, even though the wait check passed right before the send keys and the username field has no issues entering the text. I get this error:
> org.openqa.selenium.ElementNotInteractableException: Element is not
> visible Build info: version: '3.7.1', revision: '8a0099a', time:
> '2017-11-06T21:01:39.354Z' System info: host: 'D2QZ7XF2', ip:
> '10.122.22.31', os.name: 'Windows 10', os.arch: 'amd64', os.version:
> '10.0', java.version: '1.8.0_151' Driver info:
> org.openqa.selenium.firefox.FirefoxDriver Capabilities
> {acceptInsecureCerts: true, browserName: firefox, browserVersion:
> 57.0, javascriptEnabled: true, moz:accessibilityChecks: false, moz:headless: false, moz:processID: 15884, moz:profile:
> C:\Users\dcollier\AppData\L..., moz:webdriverClick: false,
> pageLoadStrategy: normal, platform: XP, platformName: XP,
> platformVersion: 10.0, rotatable: false, timeouts: {implicit: 0,
> pageLoad: 300000, script: 30000}} Session ID:
> b2f9536b-23ce-4c0f-93d5-cfe46d82228d
>
> at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native
> Method) at
> sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
> at
> sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
> at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
> at
> org.openqa.selenium.remote.http.W3CHttpResponseCodec.createException(W3CHttpResponseCodec.java:187)
> at
> org.openqa.selenium.remote.http.W3CHttpResponseCodec.decode(W3CHttpResponseCodec.java:122)
> at
> org.openqa.selenium.remote.http.W3CHttpResponseCodec.decode(W3CHttpResponseCodec.java:49)
> at
> org.openqa.selenium.remote.HttpCommandExecutor.execute(HttpCommandExecutor.java:164)
> at
> org.openqa.selenium.remote.service.DriverCommandExecutor.execute(DriverCommandExecutor.java:83)
> at
> org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:600)
> at
> org.openqa.selenium.remote.RemoteWebElement.execute(RemoteWebElement.java:279)
> at
> org.openqa.selenium.remote.RemoteWebElement.sendKeys(RemoteWebElement.java:100)
I also tested with latest Chrome driver and it worked fine there as well. But we need to use firefox profiles, so i need this to work there. Appears to be an issue with the gecko driver, has anyone encountered this, know of a solution? I tried several approaches but it never works.

How do I check enable and disabled button using helium?

The code of attached button is:
<div style="position: absolute; right: 0; top: 0;">
<button class="prev btn btn-warning disabled" style="padding: 4px 8px;">
<i class="fa fa-chevron-left" style="margin: 0"/>
</button>
<button class="next btn btn-warning" style="padding: 4px 8px;">
<i class="fa fa-chevron-right" style="margin: 0"/>
</button>
</div>
How can I check that which one is enable using helium
I tried the following code
click("Home");
if(Button(">").isEnabled()){
click($("html/body/div[6]/div/h3/div/button[2]"));
}
else{
click($("html/body/div[6]/div/h3/div/button[1]"));
}
But got the following error
Exception in thread "main" org.openqa.selenium.NoSuchElementException:
Cannot find element ButtonImpl(">").
For documentation on this error, please visit: http://seleniumhq.org/exceptions/no_such_element.html
Build info: version: '2.45.0', revision: '5017cb8e7ca8e37638dc3091b2440b90a1d8686f', time: '2015-02-27
09:10:26'
System info: host: 'Keya-PC', ip: '172.16.0.144', os.name: 'Windows 7', os.arch: 'amd64', os.version: '6.1', java.version:
'1.8.0_25'
Driver info: driver.version: unknown
at com.heliumhq.api_impl.GUIElementImpl.perform(GUIElementImpl.java:107)
at com.heliumhq.api_impl.GUIElementImpl.bindToFirstOccurrence(GUIElementImpl.java:94)
at com.heliumhq.api_impl.GUIElementImpl.getFirstOccurrence(GUIElementImpl.java:89)
at com.heliumhq.api_impl.ButtonImpl.isEnabled(ButtonImpl.java:26)
at com.heliumhq.API$Button.isEnabled(API.java:1276)
at searchHomePage.search(searchHomePage.java:30)
at mainClass.main(mainClass.java:19)
error: Cannot find element ButtonImpl(">")
We need to check the presence of the class (prev btn btn-warning disabled or next btn btn-warning ) in the code.
element ">" is not on the page is a picture.
UPD:
if (driver.findElements(By.xpath("someXpath")).size == 0)
or
$(By.xpath("someXpath")).shouldNotBe(visible);
Code in Java:
public static boolean isElementPresent(By by) {
try {
driver.findElement(by);
return true;
} catch (NoSuchElementException e) {
return false;
}
}

DataTables warning: Requested unknown parameter '4' from the data source for row ''

Are Days and days that I'm looking for this problem, but nothing resolved it!
This warning appear after the add of a Student to my Database. The persist of the Data is Ok, so i need to hide this error or adjust it.
So i have a Datables that give me this error:
This is my html code:
<script type="text/javascript">
$(document).ready(function () {
$("#companies").dataTable({
"bServerSide": true,
"sAjaxSource": "/studentiSource",
"bProcessing": true,
"sPaginationType": "full_numbers",
"bJQueryUI": true,
"aoColumns": [
{ "sName": "ID", "mDataProp": null,
"bSearchable": false,
"bSortable": false,
"bVisible": false
},
{ "sName": "NOME",},
{ "sName": "COGNOME"},
{ "sName": "USERNAME"},
{ "sName": "PASSWORD" },
{ "fnRender": function (oObj) {
console.log(oObj);
return '<a href=${pageContext.request.contextPath}/modificaStudente.jsp?id=' + oObj.aData[0] + '>' + 'Gestisci' + '</a>';
}}
]
}).makeEditable({
sUpdateURL : "/updateStudenti" ,
sAddURL: "/studenteServlet",
sDeleteURL: "/deleteStudenti",
fnShowError: function (message, action) {
switch (action) {
case "update":
jAlert(message, "Update failed");
break;
case "delete":
jAlert(message, "Delete failed");
break;
case "add":
$("#lblAddError").html(message);
$("#lblAddError").show();
break;
}
},
fnStartProcessingMode: function () {
$("#processing_message").dialog();
},
fnEndProcessingMode: function () {
$("#processing_message").dialog("close");
}
});
});
And the table is:
<div id="container">
<div id="demo_jui">
<button id="btnAddNewRow" value="Ok">Aggiungi nuovo studente...</button>
<button id="btnDeleteRow" value="cancel">Rimuovi utente selezionato</button>
<div id="processing_message" style="display:none" title="Processing">Attendere.. Caricamento dati in corso</div>
<table id="companies" class="display">
<thead>
<tr>
<th>ID</th>
<th>Nome</th>
<th>Cognome</th>
<th>Username</th>
<th>Password</th>
<th>Dispense</th>
</tr>
</thead>
<tbody >
</tbody>
</table>
</div>
<form id="formAddNewRow" action="#" title="Aggiungi nuovo studente">
<label id="lblAddError" style="display:none" class="error"></label>
<input type="hidden" id="id" name="id" value="-1" rel="0" />
<input type="hidden" value="aggiungi" name="action">
<label for="name">Nome</label><input type="text" name="nome" id="name" class="required" rel="1" />
<br />
<label for="name">Cognome</label><input type="text" name="cognome" id="address" rel="2" />
<br />
<label for="name">Username</label><input type="text" name="username" id="postcode"/>
<br />
<label for="name">Password</label><input type="text" name="password" id="town" rel="3"/>
<br />
</form>
</div>
I'm using Datatables 1.9.4
I cant give you a definitive answer, since you did not include the JSON response from the server.
This message usally means that DataTables is looking at your data source for array position 4 (which is the fifth element -- the password field) and not finding it.
You should make sure that you are returning a response with all the fields specified in the datatables definition, including the password field.
The sixth element of your JSON array doesn't contain the value for key '4' because you're fetching a null value, try to parse your JSON array to http://jsoneditoronline.org/ and you'll see it.