Perform Click on an Element - javascript

I am working on Selenium WebDriver.
I need to point the mouse to an element and perform click on it and I want to use javascript here instead of Xpaths.
The javascript of that element is not a method so that I can just fire it directly.
I am confused how to create a javascript so that the method when auto-executed should go to that object (I want to point to that object using its javascript only) and perform click.
Element's javascript:
javascript:setParam(paramOrderNbr, '4');
go('survey_editing.jsp','actMoveItemUp);
Please help!
Kumar

try this:
String cssSelector =.... //css selector of the element you want click on
JavascriptExecutor js = (JavascriptExecutor) driver;
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("var x = $(\'"+cssSelector+"\');");
stringBuilder.append("x.click();");
js.executeScript(stringBuilder.toString());
hope this works for you

Good job.
But try to modify a lil bit your css selector.
Try simply map[name="edit_1"]> area
But before you try to execute anuthing verify with firebug ( i use firepath, firebug addon in ffox) to verify that your css selector is correct.
Then try execute the code I mentioned above. It always works.
But also is possible to try another approach. If your selenium test is connected with pointing out web element with onmousehover action handling.
Then is possible to user action builder:
WebElement mnuElement;
WebElement submnuElement;
mnEle = driver.findElement(By.Id("mnEle")).click();
sbEle = driver.findElement(By.Id("sbEle")).click();
Actions builder = new Actions(driver);
// Move cursor to the Main Menu Element
builder.moveToElement(mnEle).perform();
// Giving 5 Secs for submenu to be displayed
Thread.sleep(5000L);
// Clicking on the Hidden SubMenu
driver.findElement(By.Id("sbEle")).click();
please inform as soon as you check this one.

I've made a little investigation on your problem. And now I'ma a lil bit frustrated.
Firebug is unable to locate anything which is contained in <script> tags.
See the picture below
So if we are unable of locating element using standard tree DOM model then the last assumption is left (in my opinion). I'll share only the idea I would implement if come across with your problem. Simply try to click on fixed coordinates using js.But this is considered to be bad approach. It is explained here
So returning back to the js locating coordinates to click you can use this
Using described part we locate x, y coordinates of the element we need to locate. And using this
you can actually perform the click.
Something like that:
JavascriptExecutor js = (JavascriptExecutor) driver;
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("x.trigger("click", [x, y]);"); //where [x,y] you've already //obtained
js.executeScript(stringBuilder.toString());
By the way, you can get to know about advanced user actions here . I find it quite helpful in some cases.
But it still seems to me that somehow it is possbile to locate your needed element in DOM.
Hope my answer helps somehow)

Related

Selenium Webdriver css selector onclick event for flight booking website

I am trying automation test on following website - http://www.arzoo.com
when we search flight,
I am unable to click select on particular flight.
I used Xpath but it doesn't get the element if it's at bottom or middle of the page so then I need to use:
JavascriptExecutor jsx2 = (JavascriptExecutor)driver;
jsx2.executeScript("window.scrollBy(0,750)", "");
driver.findElements(By.xpath("//a[text()='Select']")).get(15).click();
but I don't want to use scroll to position. different screens will need different sizes.
I planned to use css sector but still no success.
Try the following xpath:
driver.findElement(By.xpath("//a[contains(#class, 'btn-primary')]")).click();
if not, try
driver.findElement(By.xpath("//li[contains(#id, 'result_0')]/div/div/div/div[2]/a")).click();
See the following for reference:
Get Nth child of a node using xpath
Xpath changing after the page gest loaded every time
Wrap the below code inside executeScript()
let allSelectButtons = document.querySelectorAll(".booking-item-flight-details .booking-item-arrival a");
for(i=0;i<allSelectButtons.length;i++) {
allSelectButtons[i].click();
}

Click on pseudo element using Selenium

I am trying to use Selenium to click on a ::after pseudo element. I realize that this cannot be done through the WebDriver directly, but cannot seem to figure out a way to do so with Javascript.
Here is what the DOM looks like:
<em class="x-btn-split" unselectable="on" id="ext-gen161">
<button type="button" id="ext-gen33" class=" x-btn-text">
<div class="mruIcon"></div>
<span>Accounts</span>
</button>
::after
</em>
This is what the above element looks like. The Left hand side of the object is the 'button' element and the :after element is the right hand side with the arrow which would bring down a dropdown menu when clicked. As you can see that the right hand side has no identifiers whatsoever and that is partially what is making this difficult to do.
I have seen these two links in stackoverflow and have attempted to combine the answers to form my solution, but to no avail.
Clicking an element in Selenium WebDriver using JavaScript
Locating pseudo element in Selenium WebDriver using JavaScript
Here is one my attempts:
string script = "return window.getComputedStyle(document.querySelector('#ext-gen33'),':before')";
IJavaScriptExecutor js = (IJavaScriptExecutor) Session.Driver;
js.ExecuteScript("arguments[0].click(); ", script);
In which I get this error:
System.InvalidOperationException: 'unknown error: arguments[0].click is not a function
(Session info: chrome=59.0.3071.115)
(Driver info: chromedriver=2.30.477700 (0057494ad8732195794a7b32078424f92a5fce41),platform=Windows NT 6.1.7601 SP1 x86_64)'
I've also tried using the Actions class in Selenium to move the mouse in reference to the left hand side, similar to this answer as well. I think it may be because I don't know what the offset is measured in and the documentation doesn't seem to give any indication. I think it is in pixels??
Actions build = new Actions(Session.Driver);
build.MoveToElement(FindElement(By.Id("ext-gen33"))).MoveByOffset(235, 15).Click().Build().Perform();
This attempt seems to click somewhere as it gives no errors, but I'm not really sure where.
I'm attempting to automate Salesforce (Service Cloud) in c# if that helps.
Maybe someone can offer a solution?
I've encounter the same problem while writing Selenium tests for Salesforce and managed to solve it by direct control over mouse using Actions.
Wrapper table for this button has hardcoded width of 250px, and you have spotted that. To locate where the mouse is, you can use contextClick() method instead of Click(). It simulates right mouse button so it will always open browser menu.
If you do:
Actions build = new Actions(Session.Driver);
build.MoveToElement(FindElement(By.Id("ext-gen33"))).ContextClick().Build().Perform();
you will spot that mouse moves to the middle of the WebElement, not the top left corner (I thought that it does too). Since that element width is constant, we can move mouse just by 250 / 2 - 1 to the right and it will work :)
code:
Actions build = new Actions(Session.Driver);
build.MoveToElement(FindElement(By.Id("ext-gen33"))).MoveByOffset(124, 0).Click().Build().Perform();
For those who are trying to do this in Python, the solution is below:
elem= driver.<INSERT THE PATH TO ELEMENT HERE>
ActionChains(driver).move_to_element_with_offset(elem,249,1).click().perform()
Basically here I'm finding my element in the DOM and assigning to a WebElement. The WebElement is then passed the method move_to_element_with_offset as a param.
I got the px values for the element from developer tools.
PS: use this import- from selenium.webdriver.common.action_chains import ActionChains
You can read more about Action chain class and its method move_to_element_with_offset here: http://selenium-python.readthedocs.io/api.html.
Hope this helps.
Maciej'a answer above worked with WebDriver, but not with the RemoteWebDriver (Selenium 3.12.0) against Firefox V.56. We needed a solution that worked for both local and remote. Ended up using keyboard shortcuts to invoke the Navigation Menu drop down. As an added benefit, this also removes the need to use offsets.
String navigationMenuDropdownShortcutKeys = Keys.chord(Keys.ESCAPE, "v");
new Actions(driver)
.sendKeys(navigationMenuDropdownShortcutKeys)
.perform();
Im going to provide an alternative that may work for some scenarios, at least it did the trick for me, and is relatively easy to implement in any language using selenium via a JS script.
In my scenario there was an ::after pseudoelement containing the functionality of a button. This button was contained in a position relative to another element under it.
So I did the following:
Get the element that I can, in this question scenario would be that span.
Get the coordinates of the element.
Calculate the coordinates realtive to that element of the pseudoelement you want to click.
Click on those coordinates.
This is my code using perl, but I'm sure you can do the same in any language:
my $script="
function click_function(x, y)
{
console.log('Clicking: ' + x + ' ' + y);
var ev = new MouseEvent('click', {
'view': window,
'bubbles': true,
'cancelable': true,
'screenX': x,
'screenY': y
});
var el = document.elementFromPoint(x, y);
el.dispatchEvent(ev);
}
var element = document.getElementById('here_put_your_id'); //replace elementId with your element's Id.
var rect = element.getBoundingClientRect();
var elementLeft,elementTop; //x and y
var scrollTop = document.documentElement.scrollTop?
document.documentElement.scrollTop:document.body.scrollTop;
var scrollLeft = document.documentElement.scrollLeft?
document.documentElement.scrollLeft:document.body.scrollLeft;
elementTop = rect.top+scrollTop;
elementLeft = rect.left+scrollLeft;
console.log('Coordiantes: ' + elementLeft + ' ' + elementTop)
click_function(elementLeft*1.88, elementTop*1.045) // here put yor relative coordiantes
";
$driver->execute_script($script);
After going through numerous article and the blogs I figured out the way to determine how to detect the Pseudo element in the DOM in the Selenium. And validate based on the certain conditions if it is present or no.
Step 1
Find the path to the parent element which consist the pseudo element and pass under the findElement as shown below
WebElement pseudoEle = driver.findElement(path);
Step 2
String display = ((JavascriptExecutor)getWebDriver()).executeScript("return window.getComputedStyle(arguments[0], ':after').getPropertyValue('display');",pseudoEle).toString();
In the above line of code pass the desired Pseudo code in the place of ":after" (In my case I was looking for 'after') and the property value which is changing based on the pseudo code is present or no (In my case it was 'display').
Note: When the pseudo element was present javascript code return 'Block' which in turn I saved in the display field. And use it according to the scenario.
Steps to determine the right property value for your case
Inspect the element.
Navigate to the parent element of the pseudo code.
Under the Styles tab figure out the field(Green in color) whose value change when the pseudo code is present and when not present.
I am sure this would help you to the great extent. Kindly like and support, would encourage me to post more solutions as such.
Thanks!

Findelement in selenium and retain value in json page

I know there has been a several threads regarding the same question, but none of them worked for me. I have two questions.
Is there any other way to get the element other than using xpath, as I am using the below code to select the line number 9 in the json page, what if the line number changes in a new page. So I want to get the value by some other way.
WebElement ele = driver1.findElement(By.xpath("//[#id='aceEditor']/div[2]/div/div[3]/div[9]/div/span[2]"));
I am updating the double quoted string in line 9(Test_Password) , It is a password and I am changing it using Javascript using below code. Though the value is updated , after a page refresh the value is getting changed to the original value. It is a password and after setting when I go and login with the new password I am not able to do that. I want the values to remain same even after page refresh. Please help me with the code.
Javascript I use:
WebElement ele = driver1.findElement(By.xpath("//*[#id='aceEditor']/div[2]/div/div[3]/div[9]/div/span[2]"));
((JavascriptExecutor)driver1).executeScript("arguments[0].innerText = '"+ replace_text + "'", ele);
HTML Code:
<div class="ace_line" style="height:14px"> <span class="ace_variable">"value"</span>: <span class="ace_string">"Test_password"</span>,</div>
Is there any other way to get the element other than using xpath
Yes, there is other way instead of using xpath to get the same element. You should try using By.cssSelector() as below :-
WebElement ele = driver1.findElement(By.cssSelector("span.ace_string"));
Or
WebElement ele = driver1.findElement(By.cssSelector("#aceEditor span.ace_string"));
Or using By.className() it this element has unique class name as below :-
WebElement ele = driver1.findElement(By.className("ace_string"));
I want the values to remain same even after page refresh.
No, you can't achieve this. Actually it just happens at runtime. You're just temporary changing inner text of the element which wouldn't be effected to change the actual content forever unless you can perform some action to update password which to be store into DB or other place for the backup which will see effect later.

Selenium c# how to findElement by JavaScript?

I'm working with an old portal and I have to use IE. There are some things that it doesn't find, cause it's part of a <td> menu, I tried to find it by XPath, but doesn't help.
I found the form is being rendered by a JavaScript function. And I'd like to click on them just to execute it, but how can I locate the page elements using selenium WebDriver??
For example: if I had this code
<div class="logout-link ng-scope"
ng-click="login("github")"
ng-show="!me" ng-controller="MenuCtrl">login</div>
How can I execute the ng-click part with the Selenium WebDriver?
Make sure you're trying to find element in the same frame it is located. Answer example: How to switch between frames in Selenium WebDriver using Java
Try to wait for element to appear and be available: http://www.seleniumhq.org/docs/04_webdriver_advanced.jsp
Hopefully you know how to find elements via JS (document.getElementsByClassName('logout-link ng-scope')) and here is answer on hot to use JS in C#: Execute JavaScript using Selenium WebDriver in C# - only difference is that you don't need to return anything - you only need to '.click()'
Why do you want to execute Javascript to locate an element??? Try using WebDriverWait to wait until element visible and clickable as below :-
var wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
var Login = wait.Until(ExpectedConditions.ElementToBeClickable(By.Xpath("//div[text() = 'login']")));
Login.Click();
Note :- make sure before try this element is not inside any frame
Hope it helps.....:)
Clicking on the web element you create executes the associated function. Look via CSS Selector against the ng-click:
IWebElement elem = driver.FindElement(By.CssSelector("div[ng-click=login("github")]"));
elem.click();
You could also build an action to move to the element and then click on it:
IWebElement elem = driver.FindElement(By.CssSelector("div[ng-click=login("github")]"));
Actions action = new Actions(driver);
action.MoveToElement(elem).Click().Build().Perform();

How to find selector for a random ID, XPATH & CSSpath, I'm testing a CMS tool with Selenium c#

Problem: Hi Guys, I'm testing a CMS tool using selenium c# but problem is to find a selector for a tiny drop down button because of random ID(all selectors). While it is generating HTML codes but i can not take the help of it as the next time when script runs it changes the IDs (Class name and all other identifiers).
Tried : i tried storing Xpaths of all drop down button on page in an array and next time clicking on the array position of the element but it didnt store any element xpath in array.
please suggest what can i do in this case, possibly its a case of java script enabled page.
HTML Code of element:
<span class="epi-extraIcon epi-pt-contextMenu epi-iconContextMenu" role="presentation" title="Display menu" data-dojo-attach-point="iconNodeMenu" _dijitmenuuniqname_51_43="1"/>
Recently I used selenium in C# and had a few problems like that.
My solution was to use XPath.
I inspected the elements that I needed with firebug (on Mozilla Firefox) to get the Xpath.
After that, I used HtmlAgilityPack nuget to load the page source and select the nodes and then I was able to get the elements.
I also disabled the JQuery animations of the page to avoid some problems.
So, my code for the selection of the nodes was something like that:
var document = new HtmlDocument();
document.LoadHtml(pageSource);
var htmlLoaded = DocumentParsing(document.DocumentNode.SelectNodes(
"/html/body/table[2]/tbody/tr/td/table[2]/tbody/tr/td[1]/font[2]/b[1] |" +
"/html/body/table[2]/tbody/tr/td/table[2]/tbody/tr/td[1]/font[2]/b[2]));
And my code for disable JQuery animations:
try
{
var js = DriverService as IJavaScriptExecutor;
js.ExecuteScript("$.fx.off = !$.fx.off;");
return true;
}
catch (Exception)
{
return false;
}
Hope that helps.

Categories

Resources