Selenium Webdriver css selector onclick event for flight booking website - javascript

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

Related

How can we determine when to use JavaScriptExecutor in selenium c#?

TestInChrome1 throws me an exception - "OpenQA.Selenium.ElementNotInteractableException: element not interactable" However, when JavaScriptExecutor is used in TestInChrome2, it works well.
My questions are:
why does Click() method is not working in TestInChrome1?
how do can we determine that JavaScriptExecutor is necessary without trial and errors?
[TestMethod]
public void TestInChrome1()
{
IWebDriver driver = new ChromeDriver();
driver.Navigate().GoToUrl("https://ultimateqa.com/");
IWebElement element = driver.FindElement(By.TagName("title"));
element.Click();
driver.Quit();
}
[TestMethod]
public void TestInChrome2()
{
IWebDriver driver = new ChromeDriver();
driver.Navigate().GoToUrl("https://ultimateqa.com/");
IWebElement element = driver.FindElement(By.TagName("title"));
IJavaScriptExecutor js = (IJavaScriptExecutor)driver;
string title = (string)js.ExecuteScript("return document.title");
driver.Quit();
}
The <title> tag is required in all HTML documents and it defines the title of the document. The element:
Defines a title in the browser toolbar.
Provides a title for the page when it is added to favorites.
Displays a title for the page in search-engine results.
Note A: You can NOT have more than one element in an HTML document.
Note B: If you omit the <title> tag, the document will not validate as HTML.
If you observe the HTML DOM of any website e.g. https://ultimateqa.com/ you will observe the <title> resides within the <head>. Hence the information of this tag is visible and readable but not interactable.
TestInChrome1()
So as per the discussion above, in TestInChrome1():
You won't be able to invoke Click() on the title tag.
To extract the title you can use the Title property from IWebDriver Interface and you can use the following solution:
Console.WriteLine(driver.Title);
TestInChrome2()
By now you must be aware that Selenium beside allowing users to simulate common activities performed by end-users, entering text into fields, selecting drop-down values and checking boxes, and clicking links in documents, it also provides many other controls such as arbitrary JavaScript execution. To extract the <title> you can use the ExecuteScript() method from IJavaScriptExecutor interface as follows:
Console.WriteLine((string)((IJavaScriptExecutor)driver).ExecuteScript("return document.title"));
When we use selenium, it has methods written in such a way that it tries to emulate how user will interact with the webpage.
So, lets take the case there is a button on the screen but it never displays on the visible area of the screen. Maybe it is not scrollable (or maybe it is always hidden) and will be never be available to user. Now this is a valid bug.
If you use javascript executor, it will click on the buttob and your script won't be able to catch this issue
If you use selenium method for click, script will fail giving you some exception
In my case, I have encountered Element not interactable exception in mostly false positive (invalid, non-bug) scenarios
if some field on screen was inactive earlier, you performed some action it became active. but due to faster execution, it was still inactive, when script interacted with it
Say you have dropdown on screen, you expand the dropdown and click on some field. Now you click some other field when dropdown was closed. While execution dropdown does not close immediately and element you want to access next is obsecured by that dropdown (can happen for popups, or some element that expands on screen, combobox, searchbox)
If you see too many issues due to element not interactable , just catch this exception, take screenshot for your reference, generate a warning in logs for yourself and you can implement direct click using javascript executor in catch block.
Atleast by generating warning for yourself, you can check if you are not missing out on an actual issue.
Hope this helps.

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 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.

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