Selenium not finidng element id - java

I've just begun using selenium web-driver. I'm trying to use it login and navigate/scrape.
public static void main(String[] args) {
java.util.logging.Logger.getLogger("com.gargoylesoftware.htmlunit").setLevel(java.util.logging.Level.OFF);
java.util.logging.Logger.getLogger("org.apache.http").setLevel(java.util.logging.Level.OFF);
WebDriver driver = new HtmlUnitDriver(BrowserVersion.CHROME);
driver.get("my_Site_I_Reference");
#SuppressWarnings("unused")
WebDriverWait wait = new WebDriverWait(driver, 4000);
WebElement name = driver.findElement(By.id("LoginUsername"));
name.sendKeys("exampleName");
name.submit();
System.out.println("Page title is: " + driver.getTitle());
driver.quit();
}
I'm using the code above to try and enter a username into the username field but I am constantly met with this error:
"org.openqa.selenium.NoSuchElementException: Unable to locate element with ID: LoginUsername"
I'm almost certain the element is called LoginUsername as shown in the picture:
Any help would be very much appreciated, thanks!

It would be still a guess, but I suspect the element is inside an iframe. If this is the case, switch to the iframe before looking for the element:
driver.switchTo().frame("frame_id_or_name");
WebElement name = driver.findElement(By.id("LoginUsername"));

Can you please share HTML code in detail ? Meanwhile, You can also give a try by changing it to below and share what do you see?
WebElement name = driver.findElement(By.xpath(“//*[#id="LoginUsername"]”));
OR
WebElement name = driver.findElement(By.xpath(“//input[#id="LoginUsername"]”));

Turns out that I had Javascript disabled by default I found this out by printing the page source my code loaded
((HtmlUnitDriver) driver).setJavascriptEnabled(true);
Once enabled selenium behaved like I expected

Related

Selenium: ElementNotInteractableException: element not interactable when trying to access autoComplete text box

I am stuck with the WebElement which I am trying to access on the Webpage with the below code but still getting mentioned error. The Element allows to autocomplete the subjects and multiple subjects to be entered in the single text box.
WebElement Subjects = driver.findElement(By.xpath("//*[#id='subjectsContainer']"));
JavascriptExecutor executor = (JavascriptExecutor)driver;
executor.executeScript("arguments[0].click();", Subjects);
String subject1 = prop.getProperty("subject1");
String subject2 = prop.getProperty("subject2");
String subject3 = prop.getProperty("subject3");
Subjects.sendKeys(subject1);
Subjects.sendKeys(Keys.ENTER);
Subjects.sendKeys(subject2);
Subjects.sendKeys(Keys.ENTER);
Subjects.sendKeys(subject3);
Subjects.sendKeys(Keys.ENTER);
driver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
WebElement accepts the multiple subjects to be entered by user which autocompletes
Selenium WebElement error
Looks like you need to add some delay or element visibility validation before you trying to send text to this element.
Additionally it's not recommended to use JavaScript click instead of WebDriver click unless you have no choice.
Please find below answer for my query as it is now working fine after putting Explict wait condition and locating correct webElement with tagname 'input'.
//Load the data from the Properties file
String subject1 = prop.getProperty("subject1");
String subject2 = prop.getProperty("subject2");
String subject3 = prop.getProperty("subject3");
//WebElement to capture the visibility condition
WebElement Subjects =driver.findElement(By.xpath("//*[#id='subjectsContainer']"));
WebDriverWait wait = new WebDriverWait(driver, 10);
wait.until(ExpectedConditions.elementToBeClickable(Subjects)).click();
WebElement Sub1 = driver.findElement(By.xpath("//input[#id='subjectsInput']"));
wait.until(ExpectedConditions.presenceOfElementLocated(By.xpath("//input[#id='subjectsInput']")));
Sub1.sendKeys(subject1); //Send first Subject
Sub1.sendKeys(Keys.ENTER);
wait.until(ExpectedConditions.presenceOfElementLocated(By.xpath("//input[#id='subjectsInput']")));
System.out.println("ENtered subject 1" + subject1);
Sub1.sendKeys(subject2); //Send second subject
Sub1.sendKeys(Keys.ENTER);
System.out.println("ENtered subject 2" + subject2);
wait.until(ExpectedConditions.presenceOfElementLocated(By.xpath("//input[#id='subjectsInput']")));
Sub1.sendKeys(subject3); //Send thrid subject
Sub1.sendKeys(Keys.ENTER);
System.out.println("ENtered subject 3" + subject3);
A quick and dirty solution to many not interactable errors is simply this:
Thread.sleep(500);
I find this tactic to be extremely useful in quickly debugging problematic elements before implementing a more performant and elegant wait solution like you mentioned in your update.

How to interact with the elements within #shadow-root (open) while Clearing Browsing Data of Chrome Browser using cssSelector

I had been following the discussion How to automate shadow DOM elements using selenium? to work with #shadow-root (open) elements.
While in the process of locating the Clear data button within the Clear browsing data popup, which appears while accessing the url chrome://settings/clearBrowserData through Selenium I am unable to locate the following element:
#shadow-root (open)
<settings-privacy-page>
Snapshot:
Using Selenium following are my code trials and the associated errors encountered:
Attempt 1:
WebElement root5 = shadow_root4.findElement(By.tagName("settings-privacy-page"));
Error:
Exception in thread "main" org.openqa.selenium.JavascriptException: javascript error: b.getElementsByTagName is not a function
Attempt 2:
WebElement root5 = shadow_root4.findElement(By.cssSelector("settings-privacy-page"));
Error:
Exception in thread "main" org.openqa.selenium.NoSuchElementException: no such element: Unable to locate element: {"method":"css selector","selector":"settings-privacy-page"}
Attempt 3:
WebElement root5 = (WebElement)((JavascriptExecutor)shadow_root4).executeScript("return document.getElementsByTagName('settings-privacy-page')[0]");
Error:
Exception in thread "main" java.lang.ClassCastException: org.openqa.selenium.remote.RemoteWebElement cannot be cast to org.openqa.selenium.JavascriptExecutor
Incase if it is helpful the initial code block (till the above line) works perfect:
driver.get("chrome://settings/clearBrowserData");
WebElement root1 = driver.findElement(By.tagName("settings-ui"));
WebElement shadow_root1 = expand_shadow_element(root1);
WebElement root2 = shadow_root1.findElement(By.cssSelector("settings-main#main"));
WebElement shadow_root2 = expand_shadow_element(root2);
WebElement root3 = shadow_root2.findElement(By.cssSelector("settings-basic-page[role='main']"));
WebElement shadow_root3 = expand_shadow_element(root3);
WebElement root4 = shadow_root3.findElement(By.cssSelector("settings-section[page-title='Privacy and security']"));
WebElement shadow_root4 = expand_shadow_element(root4);
PS: expand_shadow_element() works flawless.
If you are trying to get 'Clear Data' element then you can use the below js to get the element and then perform.
return document.querySelector('settings-ui').shadowRoot.querySelector('settings-main').shadowRoot.querySelector('settings-basic-page').shadowRoot.querySelector('settings-section > settings-privacy-page').shadowRoot.querySelector('settings-clear-browsing-data-dialog').shadowRoot.querySelector('#clearBrowsingDataDialog').querySelector('#clearBrowsingDataConfirm')
Here is the sample script.
driver.get("chrome://settings/clearBrowserData");
driver.manage().window().maximize();
JavascriptExecutor js = (JavascriptExecutor) driver;
WebElement clearData = (WebElement) js.executeScript("return document.querySelector('settings-ui').shadowRoot.querySelector('settings-main').shadowRoot.querySelector('settings-basic-page').shadowRoot.querySelector('settings-section > settings-privacy-page').shadowRoot.querySelector('settings-clear-browsing-data-dialog').shadowRoot.querySelector('#clearBrowsingDataDialog').querySelector('#clearBrowsingDataConfirm')");
// now you can click on clear data button
clearData.click();
Edit 2: Explanation
Problem: Selenium does not provide explicit support to work with Shadow DOM elements, as they are not in the current dom. That's the reason why we will get NoSuchElementException exception when try to access the elements in the shadow dom.
Shadow DOM:
Note: We will be referring to the terms shown in the picture. So please go through the picture for better understanding.
Solution:
In order to work with shadow element first we have to find the shadow host to which the shadow dom is attached. Here is the simple method to get the shadow root based on the shadowHost.
private static WebElement getShadowRoot(WebDriver driver,WebElement shadowHost) {
JavascriptExecutor js = (JavascriptExecutor) driver;
return (WebElement) js.executeScript("return arguments[0].shadowRoot", shadowHost);
}
And then you can access the shadow tree element using the shadowRoot Element.
// get the shadowHost in the original dom using findElement
WebElement shadowHost = driver.findElement(By.cssSelector("shadowHost_CSS"));
// get the shadow root
WebElement shadowRoot = getShadowRoot(driver,shadowHost);
// access shadow tree element
WebElement shadowTreeElement = shadowRoot.findElement(By.cssSelector("shadow_tree_element_css"));
In order to simplify all the above steps created the below method.
public static WebElement getShadowElement(WebDriver driver,WebElement shadowHost, String cssOfShadowElement) {
WebElement shardowRoot = getShadowRoot(driver, shadowHost);
return shardowRoot.findElement(By.cssSelector(cssOfShadowElement));
}
Now you can get the shadowTree Element with single method call
WebElement shadowHost = driver.findElement(By.cssSelector("shadowHost_CSS_Goes_here));
WebElement shadowTreeElement = getShadowElement(driver,shadowHost,"shadow_tree_element_css");
And perform the operations as usual like .click(), .getText().
shadowTreeElement.click()
This Looks simple when you have only one level of shadow DOM. But here, in this case we have multiple levels of shadow doms. So we have to access the element by reaching each shadow host and root.
Below is the snippet using the methods that mentioned above (getShadowElement and getShadowRoot)
// Locate shadowHost on the current dom
WebElement shadowHostL1 = driver.findElement(By.cssSelector("settings-ui"));
// now locate the shadowElement by traversing all shadow levels
WebElement shadowElementL1 = getShadowElement(driver, shadowHostL1, "settings-main");
WebElement shadowElementL2 = getShadowElement(driver, shadowElementL1,"settings-basic-page");
WebElement shadowElementL3 = getShadowElement(driver, shadowElementL2,"settings-section > settings-privacy-page");
WebElement shadowElementL4 = getShadowElement(driver, shadowElementL3,"settings-clear-browsing-data-dialog");
WebElement shadowElementL5 = getShadowElement(driver, shadowElementL4,"#clearBrowsingDataDialog");
WebElement clearData = shadowElementL5.findElement(By.cssSelector("#clearBrowsingDataConfirm"));
System.out.println(clearData.getText());
clearData.click();
You can achieve all the above steps in single js call as at mentioned at the beginning of the answer (added below just to reduce the confusion).
WebElement clearData = (WebElement) js.executeScript("return document.querySelector('settings-ui').shadowRoot.querySelector('settings-main').shadowRoot.querySelector('settings-basic-page').shadowRoot.querySelector('settings-section > settings-privacy-page').shadowRoot.querySelector('settings-clear-browsing-data-dialog').shadowRoot.querySelector('#clearBrowsingDataDialog').querySelector('#clearBrowsingDataConfirm')");
Screenshot:
I had to do a similar test which required clearing browsing the chrome history. A minor difference was that I was clearing the data after going to the advanced section of the pop-up. As you are struggling to click only the "Clear data" button, I'm quite sure that you've missed one or two hierarchy elements mistakenly. Or got confused between sibling and parent elements probably. As per seeing your code, I assume that you already know that to access a particular shadow DOM element you need proper sequencing and it has been explained also quite nicely above.
Coming right at your problem now, here is my code snippet which is working correctly. The code waits until the data is cleaned and then will proceed to your next action-
public WebElement expandRootElement(WebElement element) {
WebElement ele = (WebElement) ((JavascriptExecutor) driver).executeScript("return arguments[0].shadowRoot",
element);
return ele;
}
public void clearBrowsingHistory() throws Exception {
WebDriverWait wait = new WebDriverWait(driver, 15);
driver.get("chrome://settings/clearBrowserData");
// Get shadow root elements
WebElement shadowRoot1 = expandRootElement(driver.findElement(By.xpath("/html/body/settings-ui")));
WebElement root2 = shadowRoot1.findElement(By.cssSelector("settings-main"));
WebElement shadowRoot2 = expandRootElement(root2);
WebElement root3 = shadowRoot2.findElement(By.cssSelector("settings-basic-page"));
WebElement shadowRoot3 = expandRootElement(root3);
WebElement root4 = shadowRoot3
.findElement(By.cssSelector("#advancedPage > settings-section > settings-privacy-page"));
WebElement shadowRoot4 = expandRootElement(root4);
WebElement root5 = shadowRoot4.findElement(By.cssSelector("settings-clear-browsing-data-dialog"));
WebElement shadowRoot5 = expandRootElement(root5);
WebElement root6 = shadowRoot5
.findElement(By.cssSelector("cr-dialog div[slot ='button-container'] #clearBrowsingDataConfirm"));
root6.click();
wait.until(ExpectedConditions.invisibilityOf(root6));
}
It should work properly in your case too if you don't intend to change any of the options selected by default in the pop-up (In that case, you will have to add a few more codes regarding selecting those checkboxes). Please tell me if this solves your issue. Hope this is helpful
I've added a snapshot of the the screen here too-
image
The Locator Strategy in #supputuri's answer using document.querySelector() works perfect through google-chrome-devtools
However, as the desired element opens from the shadow-dom you need to induce WebDriverWait for the elementToBeClickable() and you can you the following solution:
Code Block:
driver.get("chrome://settings/clearBrowserData");
new WebDriverWait(driver, 5).until(ExpectedConditions.elementToBeClickable((WebElement) ((JavascriptExecutor)driver).executeScript("return document.querySelector('settings-ui').shadowRoot.querySelector('settings-main').shadowRoot.querySelector('settings-basic-page').shadowRoot.querySelector('settings-section > settings-privacy-page').shadowRoot.querySelector('settings-clear-browsing-data-dialog').shadowRoot.querySelector('#clearBrowsingDataDialog').querySelector('#clearBrowsingDataConfirm')"))).click();
System.out.println("Clear data Button Clicked");
Console Output:
Clear data Button Clicked
I was getting InvalidArgumentEXception when trying to identify shadowRoot element in DOM using Selenium 4.3.0 and Chrome Version 103.0.5060.134
The solution to this is
SearchContext se= driver.findElment(By.locator("...").getShadowRoot(); return type is SearchContext
in the above line try using locator as xpath
and secondly trying to locate element using SearchContext reference e.g.
WebElement we= se.findElement(By.locator("....."));
use locater as cssSelector
And boom it works like charm
Didn't find this solution available and took me half a day to figure out
Hope this helps!!!

Cannot get Past the Login Page

I can't get pass the login page. I'm correctly grabbing the input elements, populating them, and submitting but I still end up on the original page. I'm unsure where the exact issue is and I've tried ".submit, .click, and emulated a javascript ENTER to submit the credentials.
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
//Create driver, javascript enabled
WebDriver driver = new HtmlUnitDriver(true);
driver.get("https://epicmafia.com/home");
//Get parent of login form
WebElement parent = driver.findElement(By.id("login_form"));
//Get both inputs of the login form
//First is name
//Second is password
ArrayList<WebElement> children = new ArrayList<WebElement>();
for(WebElement input : parent.findElements(By.cssSelector("input")))
children.add(input);
//Fill in name
children.get(0).sendKeys("USERNAME");
//Fill in password
children.get(1).sendKeys("PASSWORD");
//Wait for good measure
driver.manage().timeouts().implicitlyWait(4, TimeUnit.SECONDS);
//Submit credentials
children.get(1).submit();
//Double check inputs are desired values
System.out.println("The username is: " + children.get(0).getAttribute("value"));
System.out.println("The password is: " + children.get(1).getAttribute("value"));
//Check if pass login page
System.out.println("End URL is: " + driver.getCurrentUrl());
driver.quit();
}
The login page is "https://epicmafia.com/home" while the next page upon successfully logging in would be "https://epicmafia.com/lobby".
edit: for reference: the third child element is the actual "Login" button that follows the first two(username and password).
The submit() should be performed on the <form> element
WebElement parent = driver.findElement(By.id("login_form"));
// fill the fields here
parent.submit();
You can try this code :
Since I do not have credentials, after clicking on log in button it'll show an error , you can provide the username and password in respective sendKeys("") command )
public class FFFF {
static WebDriver driver;
public static void main(String[] args) throws InterruptedException {
System.setProperty("webdriver.chrome.driver", "D:\\Automation\\chromedriver.exe");
driver = new ChromeDriver();
driver.manage().window().maximize();
driver.get("https://epicmafia.com/home");
driver.findElement(By.xpath("//form[#id='login_form']/descendant::input[#placeholder='username']")).sendKeys("username");
driver.findElement(By.xpath("//form[#id='login_form']/descendant::input[#placeholder='password']")).sendKeys("password");
driver.findElement(By.xpath("//form[#id='login_form']/descendant::input[#name='submit']")).click();
}
}
To send the character sequence to the username and password fields you need to induce WebDriverWait and click() on Login button you can use the following solution:
Code Block:
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
# other lines of code
driver.get("https://epicmafia.com/home")
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "input[name='user[username]']"))).send_keys("FF")
driver.find_element_by_css_selector("input[name='user[password]']").send_keys("FF")
driver.find_element_by_css_selector("input.red[value='Login']").click()
Browser Snapshot:
After looking at replies and messing around a bit the answer wasn't an error in grabbing the elements, populating them or even submitting. The problem was coming from the timeout not working, where I'd presumably thought it was.
I moved the driver to its own method kill switch so that the initial call has indefinite time to load before being manually killed off instead of automatically killed off as the code I originally posted.
Now my problem of logging in is fixed and I have to look into why the timeout isn't working. Thank you all for the help.

Selenium in Java Error: Missing or invalid type argument for pointer action

I am getting this error "Missing or invalid type argument for pointer action" while trying to execute the below code for Selenium in Java.
public static void main(String args[]) throws InterruptedException
{
WebDriver driver = new FirefoxDriver();
driver.get("https://www.flipkart.com/");
driver.findElement(By.xpath(".//*[#class='_3Ji-EC']/li[8]/a")).click();
WebElement elem = driver.findElement(By.className("_2zrpKA"));
elem.sendKeys("ABC");
WebElement elem2 = driver.findElement(By.xpath(".//*[#class='_2zrpKA
_3v41xv']"));
elem2.sendKeys("XYZ");
driver.findElement(By.xpath(".//*[#class='_2AkmmA _1LctnI
_7UHT_c']")).click();
System.out.println("Success");
//driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
Thread.sleep(5000);
WebElement elem3 = driver.findElement(By.xpath(".//*[#class='_3Ji-
EC']/li[7]/a"));
System.out.println("success");
Actions action = new Actions(driver);
action.moveToElement(elem3).build().perform();
driver.findElement(By.xpath(".//*[#class='_1u5ANM']/li[9]/a")).click();
}
I have tried this using Selenium 3.4.0 and Firefox 51.x, 52.x, 53.x with the latest geckodriver 16.1 and 16.0 .
When I used Firefox 53.x, I was getting the error "Expected [object Undefined] undefined to be a string" else every time I am getting the error "Missing or invalid type argument for pointer action".
In the above code I am able to get "success" printed 2nd time without any problem but after that I am getting the error.
Here is the solution to your Question:
To work with Selenium 3.4.0 with geckodriver v0.16.1 & Mozilla Firefox 53.x you need to specify the absolute path of the geckodriver in your code as:
System.setProperty("webdriver.gecko.driver", "C:\\your_directory\\geckodriver.exe");
Your xpath seems petty vulnerable to me. You may want to construct more unique logical xpath. To click on Log In button you may do:
driver.findElement(By.xpath("//div[#class='AsXM8z']/ul/li/a[#class='_2k0gmP'][text()='Log In']")).click();
I would suggest you not to rely only on class, append some more properties. The xpath for Enter Email field can be:
WebElement elem = driver.findElement(By.xpath("//input[#class='_2zrpKA']"));
The xpath for Enter Password is not unique, you may like to change it to:
WebElement elem2 = driver.findElement(By.xpath("//input[#class='_2zrpKA _3v41xv']"));
The xpath for the Login button needs to be unique as follows:
driver.findElement(By.xpath("//button[#class='_2AkmmA _1LctnI _7UHT_c']")).click();
Avoid using Thread.sleep(5000); rather use ImplicitlyWait or ExplicitWait
The xpath to click on the Username is again vulnerable, you may like to change it to:
WebElement elem3 = driver.findElement(By.xpath("//div[#class='AsXM8z']/ul/li/a[#class='_1AHrFc _2k0gmP']"));
The xpath to click the Log Out button is again vulnerable, you may like to change it to:
driver.findElement(By.xpath("//div[#class='_1H5F__']/div/ul/li/ul/li/a[#class='_2k0gmP'][text()='Log Out']")).click();
Here is your own working code block with some simple tweaks;
System.setProperty("webdriver.gecko.driver", "C:\\your_directory\\geckodriver.exe");
WebDriver driver = new FirefoxDriver();
driver.get("https://www.flipkart.com/");
driver.findElement(By.xpath("//div[#class='AsXM8z']/ul/li/a[#class='_2k0gmP'][text()='Log In']")).click();
//Email
WebElement elem = driver.findElement(By.xpath("//input[#class='_2zrpKA']"));
elem.sendKeys("emailid#domain.com");
//Password
WebElement elem2 = driver.findElement(By.xpath("//input[#class='_2zrpKA _3v41xv']"));
elem2.sendKeys("pass_word");
//Login Button
driver.findElement(By.xpath("//button[#class='_2AkmmA _1LctnI _7UHT_c']")).click();
System.out.println("Success");
//driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
Thread.sleep(5000);
//Click on Name
WebElement elem3 = driver.findElement(By.xpath("//div[#class='AsXM8z']/ul/li/a[#class='_1AHrFc _2k0gmP']"));
System.out.println("success");
Actions action = new Actions(driver);
action.moveToElement(elem3).build().perform();
driver.findElement(By.xpath("//div[#class='_1H5F__']/div/ul/li/ul/li/a[#class='_2k0gmP'][text()='Log Out']")).click();
Let me know if this Answers your Question.

How to return WebElement having particular CSS property using JavascriptExecutor?

I am working on a scenario where I need to find a WebElement based on its CSS property, like background-color.
I have created the JQuery to find the element as below and it finds the webelement correctly using firefox console.
$('.search-bar-submit').each(function() {
return $(this).css('background-color') == '#fdd922';
});
Hence, I wrote the code to find this WebElement, i.e. searchbox and then tried to click it.
driver.get("http://www.flipkart.com/");
driver.findElement(By.id("fk-top-search-box")).sendKeys("iphone");
String query ="$('.search-bar-submit').each(function() { "
+ "return $(this).css('background-color') == '#fdd922'; });";
WebElement searchbox = (WebElement) ((JavascriptExecutor)driver).executeScript(query);
searchbox.click();
When I run the program, it gives me Exception in thread "main" java.lang.NullPointerException on line searchbox.click();
Can anyone help me out find the searchbox using JavascriptExecutor and then click on it? Am I missing something silly here?
Any help is appreciated. Thanks in Advance.
WebElement searchbox = (WebElement)
((JavascriptExecutor)driver).executeScript(query);
The above code calls the function but doesn't do anything with the result, ie. it doesn't return it to the caller.
Add return in the script to return the webelement to the selenium script(webdriver)
return $('.search-bar-submit').each(function() {
return $(this).css('background-color') == '#fdd922';
});
The return type is List<WebElement>so typecast it to List if you typecast it to it will throw an ClassCastException as arraylist cannot be cast to a webelement
Code:
List<WebElement> searchbox = (List<WebElement>) ((JavascriptExecutor)driver).executeScript(query);
for(int i=0;i<searchbox.size();i++){
searchbox.get(i).click();
}
EDIT:
The code was not working in firefox because the firefox browser returns a json object of the webelement.Selenium replaced its uses of org.json with gson.So it is not able to understand the response recieved
Screenshot taken from chrome
Screenshot taken from firefox
Solution
We are using Jquery get function to retrieve the DOM Elements matched by the jquery object
$('.search-bar-submit').each(function() {
return $(this).css('background-color') == '#fdd922';
}).get(0);
Code
public class jquerytest
{
public static void main(String[] args) throws Exception {
WebDriver driver = new FirefoxDriver();
driver.get("https://www.flipkart.com");
driver.findElement(By.id("fk-top-search-box")).sendKeys("iphone");
String query ="return $('.search-bar-submit').each(function() { "
+ "return $(this).css('background-color') == '#fdd922'; }).get(0);";
Thread.sleep(5000);//wait till page loads replace thread.sleep by any waits
WebElement searchbox = (WebElement) ((JavascriptExecutor)driver).executeScript(query);
searchbox.click();
}
}
I have tested the above code on both chrome and firefox it works perfectly
Hope this helps you.Kindly get back if you have any queries
I ran the following code and it all works fine. Your jquery works as well (I love the little message they print to console in the dev view hahaha).
driver.get("http://www.flipkart.com/");
WebElement in = driver.findElement(By.id("fk-top-search-box"));
in.sendKeys("iphone");
WebElement thing = driver.findElement(By.className("fk-font-bold"));
thing.click();
I believe there's a problem with your executeScript and it should be as follows.
System.out.println(((JavascriptExecutor)driver).executeScript(query, driver));
Normally the format for my calling javascript is as follows, this would be to remove the windowed attribute so that a hyperlink would open in the same tab:
String Href = linkObject.getAttribute("href");//located the hyperlink for the documents
Href = Href.substring(0, Href.length()-10)+")";//I remove ",'windowed'" from the link to stop it opening in a new window and having to change the scripts focus
JavascriptExecutor js = (JavascriptExecutor) driver;
js.executeScript("return arguments[0].href = \""+Href + "\"", linkObject););
But then you're getting JSON back and WebDriver can't understand that. See the following link for more information on that.
http://grokbase.com/t/gg/webdriver/12ckjcthg8/executing-javascript-that-returns-json-how-best-to-handle
Might I suggest this alternative, it gives the background-color in rgba format:
WebElement pain = driver.findElement(By.className("search-bar-submit");
pain.getCssValue("background-color");

Categories

Resources