Unable to click any link in the web page - javascript

I am using selenium webdriver to automate a web page. My selenium code is not identifying the link. I am getting the following error.
Exception in thread "main" org.openqa.selenium.NoSuchElementException:
no such element: Unable to locate element:
{"method":"xpath","selector":"/html/body/font/font/b/a[2]"} (Session
info: chrome=44.0.2403.89)
This is the code i am using .
public static void main(String[] args)
{
System.setProperty("webdriver.chrome.driver","C:\\Program Files (x86)\\Google\\Chrome\\chromedriver.exe");
WebDriver driver = new ChromeDriver();
driver.get("url");
driver.findElement(By.xpath("/html/body/font/font/b/a[2]")).click();
}
Thanks in advance

If you are getting NoSuchElementException as your provided exception, There are may be following reasons :-
May you are locating with incorrect xpath, So you need to share HTML for better locator solution.
May be when you are going to find element, it would not be present on the DOM, So you should implement WebDriverWait to wait until element visible and clickable as below :-
WebDriverWait wait = new WebDriverWait(driver, 10);
WebElement el = wait.until(ExpectedConditions.elementToBeClickable(By.linkText("Duty Office")));
el.click();
May be this element is inside any frame or iframe. If it is, you need to switch that frame or iframe before finding the element as below :-
WebDriverWait wait = new WebDriverWait(driver, 10);
//Find frame or iframe and switch
wait.until(ExpectedConditions.frameToBeAvailableAndSwitchToIt("your frame id or name"));
//Now find the element
WebElement el = wait.until(ExpectedConditions.elementToBeClickable(By.linkText("Duty Office")));
el.click();
//Once all your stuff done with this frame need to switch back to default
driver.switchTo().defaultContent();
Hope it helps...:)

There are two possible situation
1) you might type wrong url
2) your expected element xpath is wrong.
please validate your xpath with
this tolol : https://chrome.google.com/webstore/detail/xpath-helper/hgimnogjllphhhkhlmebbmlgjoejdpjl?hl=en
public static void main(String[] args) {
System.setProperty("webdriver.chrome.driver", "C:\Program Files (x86)\Google\Chrome\chromedriver.exe");
WebDriver driver = new ChromeDriver();
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
driver.get("Valid url");
driver.findElement(By.xpath("your valid XPATH")).click();
driver.close();
}

Related

Removing scrollbar from Selenium Screenshots

I'm getting screenshots of webpages using Chromedriver. My code works well.
I'm now attempting to remove the ugly scrollbars. Would it be possible to inject CSS into the page? I have seen a couple of similar questions, which do hint that this is possible ("You can also make Chromedriver open the url in a popup without scrollbars. You can do this using some Javascript.") but doesn't show how this is possible.
Has anybody got any idea as to how to do this?
IWebDriver driver = new ChromeDriver();
driver.Manage().Window.Size = new Size(1100, 1100);
driver.Navigate().GoToUrl("http://google.com/");
Screenshot ss = ((ITakesScreenshot)driver).GetScreenshot();
//Temp Img
string screenshot = ss.AsBase64EncodedString;
byte[] screenshotAsByteArray = ss.AsByteArray;
ss.SaveAsFile(fileNameTemp, ScreenshotImageFormat.Jpeg);
ss.ToString();
// Create a driver instance for chromedriver
IWebDriver driver = new ChromeDriver();
IJavaScriptExecutor js = (IJavaScriptExecutor)driver;
driver.Manage().Window.Size = new Size(1100, 1100);
driver.Navigate().GoToUrl(hehe[i]);
js.ExecuteScript("return document.body.style.overflow = 'hidden';");
This worked!

Selenium with headless chrome

I have testing environment which is perfectly working with chrome driver in desktop mode. I am using some javascript injections (everything works) f.e.:
public static void ForceFillInput(this Driver driver, string selector, string value)
{
var javaScriptExecutor = (IJavaScriptExecutor)driver.webDriver;
javaScriptExecutor.ExecuteScript($"$(\"{selector}\").val(\"{value}\")");
}
but when i want to run it in headless mode
AddArguments("--headless")
it will just fail on
"$ is not defined"
Can somebody help me how to inject js/jquery into headless solution?
M.
your Javascript snippet used jQuery api. In modern web development, we put Javascript at the end of HTML page to let browser to load javascript at last, so that static resources (like picture/image/text content) can display earlier as possible, withing this way to improve user experience when user open website.
I think your page also put jQuery at the end to load, try add some wait/sleep before ExecuteScript to wait browser complete load jQuery.
It looks like the shorthand for JQuery is not yet created at the time your script is executed.
Use a waiter to wait for JQuery and for the selector to be found:
public static void ForceFillInput(this Driver driver, string selector, string value)
{
string JS_SET_VALUE =
"var e; return !!window.$ && (e = window.$(arguments[0])).length > 0 && (e.val(arguments[1]), true);";
new WebDriverWait(driver, TimeSpan.FromSeconds(60))
.until(ctx => (bool)((IJavaScriptExecutor)ctx).ExecuteScript(JS_SET_VALUE, selector, value));
}

Opening a new tab using Ctrl + click combination in Selenium Webdriver

I am attempting to use ctrl + click on a link to open it in a new tab. This is working fine in Chrome 58. Please find the code below:
action.keyDown(Keys.CONTROL).click(driver.findElement(By.xpath
("//section[#class='filmStrip__basic']//a[text()='En savoir
plus']"))).keyUp(Keys.CONTROL).build().perform();
I am using the same code on IE, Firefox and Safari but getting the following error:
Firefox 54: The link is getting open in the same tab.
IE 11: Nothing happening.. the control is moving to the next line
Safari: exception on action.keyDown-Unrecognized command
Help related to any one browser is also appreciated.
Thanks
As you are trying to click on a link which is within a <a> tag, instead of xpath you can use the linkText locator. Here is the sample code with opens the url http://www.google.com, verifies the Page Title, uses Actions class to click on the Gmail link to open https://accounts.google.com in a new tab.
String URL="http://www.google.com";
System.setProperty("webdriver.gecko.driver", "C:\\Utility\\BrowserDrivers\\geckodriver.exe");
WebDriver driver = new FirefoxDriver();
driver.get(URL);
System.out.println("Page Title is : "+driver.getTitle());
WebElement link = driver.findElement(By.linkText("Gmail"));
Actions newTab = new Actions(driver);
newTab.keyDown(Keys.CONTROL).click(link).keyUp(Keys.CONTROL).build().perform();
You can find a relevant Python based solution in How to open a link embed in web element in the main tab, in a new tab of the same window using Selenium Webdriver
Another way is to use javascript executor:
JavascriptExecutor jse = (JavascriptExecutor) driver;
jse.executeScript("window.open('','_blank');");
As for your problem I had it too and didn't find anything usefull until I found this workaround.
I even tried: solution with ctrl + enter
try this way....
// specify chromedriver.exe directory path and replace in "driverPath"
String driverPath = "C:/Users......";
WebDriver driver;
System.setProperty("webdriver.chrome.driver", driverPath + "chromedriver.exe");
driver = new ChromeDriver();
System.out.println("lanuching 1st url in tab1");
driver.navigate().to(
"https://amazon.com");
System.out.println("lanuched 1st url in tab1");
Thread.sleep(30000);
((JavascriptExecutor) driver).executeScript(
"window.open('http://ebay.com');");
Thread.sleep(20000);
Set<String> allwh = driver.getWindowHandles();
System.out.println(allwh.size());
for (String v : allwh) {
System.out.println(v);
driver.switchTo().window(v);
String title = driver.getTitle();
System.out.println("2nd url in tab2" + title);

Using wait with selenium web driver async content

I am trying to automate a test on my site using selenium web driver for javascript.
How can I approach running tests here using the wait method with content that may not be ready when the page loads eg data comes from an external api etc?
In my example my content is getting loaded by an external js file. You can see what the page looks like in this fiddle I couldn't link it in my code below as the fiddle gets wrapped in an iframe.
<head>
<script src="https://cdn.auth0.com/js/lock/10.2/lock.min.js"></script>
</head>
<body onload="lock.show();">
<div id="content">
<script type="text/javascript">
var domain = 'contoso.auth0.com';
var clientID = 'DyG9nCwIEofSy66QM3oo5xU6NFs3TmvT';
var lock = new Auth0Lock(clientID, domain);
lock.show({
focusInput: false,
popup: true,
}, function (err, profile, token) {
alert(err);
});
</script>
</div>
</body>
I can get it working using sleep, but can't guarentee my content will be ready after the timeout has finished.
const {Builder, By, Key, until} = require('selenium-webdriver');
let driver = new Builder()
.forBrowser('firefox')
.build();
driver.get('MY_URL')
driver.sleep(2000).then(function() {
driver.findElement(By.name('email')).sendKeys('test#test.com')
driver.findElement(By.name('password')).sendKeys('test')
//driver.findElement(By.className('auth0-lock-submit')).click()
})
But if I try with wait
function login() {
return driver.findElement(By.name('email')).sendKeys('test#test.com')
}
driver.get('MY_URL')
driver.wait(login, 5000)
I get NoSuchElementError: Unable to locate element: *[name="email"]
How can I get this working so that I wait for my content to be available before proceeding.
The implicit wait will tell to the web driver to wait for certain amount of time before it throws a "No Such Element Exception". The default setting is 0. Once we set the time, web driver will wait for that time before throwing an exception..
driver.manage().timeouts().implicitlyWait(TimeOut, TimeUnit.SECONDS);
Try to use FluentWait. Create a by function of your element which you want to wait and pass it in below method
WebElement waitsss(WebDriver driver, By elementIdentifier){
Wait<WebDriver> wait =
new FluentWait<WebDriver>(driver).withTimeout(60, TimeUnit.SECONDS) .pollingEvery(1, TimeUnit.SECONDS).ignoring(NoSuchElementException.class);
return wait.until(new Function<WebDriver, WebElement>()
{
public WebElement apply(WebDriver driver) {
return driver.findElement(elementIdentifier);
}});
}
Code for Explicit wait:
WebDriverWait wait = new WebDriverWait(driver, 60);
WebElement element = wait.until(ExpectedConditions.presenceOfElementLocated(By.xpath("//span[contains(.,'Next')]")));
refer :-
https://www.guru99.com/implicit-explicit-waits-selenium.html

Injecting Javascript in iframe using selenium

I am a novice in selenium. I want to hit a url, search for all the iframes and in every iframe, I want to inject a Javascript code. So how would I do that. So far, I have come up with basic selenium code but do not know how to inject JS.
public class Poc {
public static void main(String[] args) {
System.setProperty("webdriver.chrome.driver","/home/xxx/xxx/xxx/chromedriver");
WebDriver driver = new ChromeDriver();
driver.manage().window().maximize();
driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
driver.get("http://www.sss.org/");
List<WebElement> elements = driver.findElements(By.tagName("iframe"));
for(WebElement element:elements) {
System.out.println(element.getAttribute("id"));
}
driver.close();
System.exit(0);
}
}
To inject code into each iframe you first have to switch to it
import org.openqa.selenium.JavascriptExecutor;
List<WebElement> elements = driver.findElements(By.tagName("iframe"));
for(WebElement element:elements) {
driver.switchTo().defaultContent();
driver.switchTo.frame(element);
if (driver instanceof JavascriptExecutor) {
((JavascriptExecutor) driver).executeScript("alert('hello world');");
}
System.out.println(element.getAttribute("id"));
}
Use JavascriptExecutor for writing javascript code in selenium
Example code for you is
JavascriptExecutor js = (JavascriptExecutor) driver;
WebElement element = driver.findElement(By.linkText("Click ME"));
js.executeScript("arguments[0].setAttribute('attr', '10')",element);

Categories