Selenium c# how to findElement by JavaScript? - 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();

Related

Selenium cannot find element in main window

I am attempting to download a file from a website using Selenium and Python 3. This requires pressing a confirmation button on an overlay window. The overlay window is not within an iFrame - the HTML is simply dynamically added when the overlay appears - but Selenium is not able to find the button by xPath, returning a NoSuchElementException. Am I missing anything that would cause Selenium not to be able to see the element as it appears in the page source? So far as I can tell, Selenium should be able to locate the button with no issue.
#Initialize Driver
driver = webdriver.Safari()
cmd = "osascript -e 'tell application \"Safari\" to set bounds of front window to {0, 22, 1500, 1022}'"
os.system(cmd)
#Call up seach link
driver.get(data_url)
wait_a = WebDriverWait(driver, 15)
element = wait_a.until(EC.presence_of_element_located((By.ID, "md-input-3")))
#Initialize and send login information (defined above)
username = driver.find_element_by_id("md-input-3")
password = driver.find_element_by_id("md-input-6")
username.send_keys(crunchbase_username)
password.send_keys(crunchbase_password)
#Click login button
password.send_keys(Keys.ENTER)
#Wait for results page to finish loading
wait = WebDriverWait(driver, 15)
element = wait.until(EC.title_contains("Signals"))
time.sleep(2)
#Press Download Button
driver.find_element_by_xpath("//button[#aria-label='Export your results']").click()
time.sleep(2)
#Press csv button
driver.find_element_by_xpath("//button[#aria-label='Export to CSV']").click()
time.sleep(2)
#Confirm downlaod
driver.find_element_by_xpath("//*[#id='cdk-overlay-36']/md-dialog-container/confirmation-dialog/dialog-layout/div/md-dialog-actions/div/button[2]").click()
#Close driver
#driver.close()
The page source is overly complicated and highly stylized so I will not include it here, but a screenshot of the relevant section of the code in my browser's web inspector is below. The element which I'm trying to click is highlighted in blue.
Web Inspector Screenshot
I appreciate any help with this.
It is hard to tell without having access to the page under question and being able to see what's going. Few general points:
Try css selectors instead of xpath. They are more robust, easier to work with and fast.
Acvoid using dynamically generated IDs. In your screenshot I can't even see an id that appears in your code.
When you have more than one element of the same kind (like buttons in your case) try getting all webelements under a certain parent and test all of them for having an attribute value that you are looking for.
For example:
elemItems = driver.find_elements_by_css_selector(menuItemSelector)
for element in elements:
if element.text == "export":
elemItems[1].click()
Here, you find all the elements of a certain type (buttons for example) and select one that has "export" text in it.
Before clicking on the element, execute the following lines:
WebElement element = driver.findElement(By.xpath(" path_of_your_module "));
((JavaScriptExecutor) driver). executeScript("argument[0].scrollIntoView(true);", element);
I faced the same issue on a dialogOverlay and I fixed it. I realized that on clicking the overlay button that would bring the overlay, selenium was searching for the element before the overlay loads the dynamic content. So I did this:
def download():
global browser
notFound = True
while(notFound):
try:
elem = browser.find_element(By.ID, 'btnFormat2')
elem.click()
notFound = False
except BaseException:
print("----Error Download Element not found")
download()
The code will continuously look for the element until its loaded on the overlay.

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();
}

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.

Unable to execute javascript in onclick using selenium

Using selenium (with python bindings), I'm dealing with a webpage that is almost entirely AJAX; including hyperlinks. Instead of using the element.click() method, I wish to execute the javascript in the "onclick" attribute of the tag:
The tag:
<a onclick="javascript:setEvent(event);requisition_openRequisitionDescription('requisitionListInterface','actOpenRequisitionDescription',_ftl_api.lstVal('requisitionListInterface', 'requisitionListInterface.listRequisition', 'requisitionListInterface.d327682e687', this),'requisitionList');return ftlUtil_followLink(this);" href="#" title="View this job description" id="requisitionListInterface.reqTitleLinkAction.row1">
The code:
from selenium import webdriver
firefox = webdriver.Firefox()
firefox.get("some_url")
elem = firefox.find_element_by_id("requisitionListInterface.reqTitleLinkAction.row1")
jcode = elem.get_attribute("onclick")
firefox.execute_script(jcode)
The Error:
WebDriverException: Message: u'event is not defined' ; Stacktrace:
Disclaimer:
I don't understand Javascript. As far as I can tell, it's expecting the 'event' variable, however I guess it has something to do with a callback ?
EDIT:
I've assumed that the javascript is modifying the href attribute but is it possible for javascript to redirect the browser without modifying the hyperlink?
You can just click it using this.
elem.click()
The onclick event will automatically get triggered.
Unless selenium does something crazy, which i doubt, onclick="javascript:setEvent(event) is not valid javascript. the rest of the string however is. When this code block gets executed, it tries to invoke a function called setEvent with the variable event, which remains undefined.
<a onclick="requisition_openRequisitionDescription('requisitionListInterface','actOpenRequisitionDescription',_ftl_api.lstVal('requisitionListInterface', 'requisitionListInterface.listRequisition', 'requisitionListInterface.d327682e687', this),'requisitionList');return ftlUtil_followLink(this);" href="#" title="View this job description" id="requisitionListInterface.reqTitleLinkAction.row1">
since event is nowhere else needed in your script, just remove it?
from selenium.webdriver.common.action_chains import ActionChains
firefox = webdriver.Firefox()
# You need a mouse to hover the span elements here, and please try this way :)
self.mouse = webdriver.ActionChains(firefox)
# You need get the span element from its xpath:
elem = firefox.find_element_by_id("requisitionListInterface.reqTitleLinkAction.row1")
# Then you hover on span element by mouse and click on it:
self.mouse.move_to_element(elem).click().perform()

Perform Click on an Element

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)

Categories

Resources