Selenium is unable to locate any element in html page - java

I'm trying to make a small java app. that can log in to my university portal, I used Selenium in the following code:
//some import statements
public class Portal{
public Portal(){
File file = new File("C:/chromedriver.exe");
System.setProperty("webdriver.chrome.driver", file.getAbsolutePath());
HtmlUnitDriver driver = new HtmlUnitDriver();
String target = "http://portal.kfupm.edu.sa/cp/home/loginf";
driver.get(target);
ArrayList <WebElement> inputs = (ArrayList<WebElement>) driver.findElements(By.tagName("input"));
System.out.println(inputs.size());
for(WebElement input : inputs){
System.out.println(input.getAttribute("value") + " " + input.getAttribute("name"));
// to insure the link is displaying something
ChromeDriver driver1 = new ChromeDriver();
driver1.get(driver.getCurrentUrl());
}
public static void main(String [] args){
new Portal();
}
}
the problem is when I use this target (my university portal) I get inputs.size() = 0; although, I'm sure there are elements with (input) tagName. Also I get the same resulst whatever was the method of (By) class I used.
However, when I change the target to any link (for example: "http://www.google.com" or "http://www.facebook.com" , I get elements in the inputs ArrayList (all elements of tagName (input) that are in the target html page). Can any body please tell me what is the problem and how can I solve it? thanks in advance..

The reason that you find zero elements with tag input is that all the elements lie inside a frame tag. Selenium is able to see to current window and all the elements that are defined inside frame tag (i.e. are inside a frameset) are invisile to it.
To see the element you will need to switch frame first, So that selenium has control inside the target frame and not in the outer window. Try this
driver.swtichTo().frame(0); // this will move selenium control inside first frame

Related

Unable to sendKeys() into input text field

I intend to automate a simple form fill Junit test on the following website: https://newdesign.millionandup.com
The input textfield i am attempting to send keys to is identified with id=email and i have tried the following two methods:
1.
WebElement passInput = driver3.findElements(By.className("sidebar__item-text")).get(0); // this xPath does the trick
wait.until(ExpectedConditions.visibilityOfElementLocated(emailLocator));
passInput.click();
passInput.sendKeys("emailID");
Thread.sleep(3000); // only to see the result
WebElement em1 = driver3.findElement(emailLocator);
JavascriptExecutor jse = (JavascriptExecutor)driver3;
//driver3.findElement(emailLocator).sendKeys(emString);
Thread.sleep(1000);
jse.executeScript("arguments[0].click()", em1);
jse.executeScript("arguments[0].value='prisoner24601#gouvernement.fr';", em1);
if (em1.isSelected()) {
System.out.println("email typed");
} else {
System.out.println("unable to send keys, element not interactable");
}
To no avail in both cases, the textfield is still not interactable and i am unable to type the data into it.
EDIT: As suggested in the comments i have attempted a third way:
3.
WebElement element = wait.until(ExpectedConditions.presenceOfElementLocated(By.xpath("//input[#id='email']")));
System.out.println("email input located");
element.click();
System.out.println("email input clicked");
element.sendKeys(emString);
Element is actually located, but, as soon as the methods click() or sendKeys() are called, the execution stops after stating "element not interactable"
The xpath - //input[#id='email'] is matching 9 elements in the DOM. Its important to find unique locators - Link to refer
And the pop-up for Register opens on mouse movement. After mouse movement, will be able to view and interact with the pop-up elements.
Used below xpath to send keys to the element Email Address and it worked for me.
//form[#id='frmLeadModal']//input[#id='email']
Try like below once, it might work for you too.
driver.get("https://newdesign.millionandup.com/#initial");
WebDriverWait wait = new WebDriverWait(driver, 30);
Actions actions = new Actions(driver);
actions.moveByOffset(100, 100).perform();
wait.until(ExpectedConditions.elementToBeClickable(By.xpath("//form[#id='frmLeadModal']//input[#id='email']"))).sendKeys("example#email.com");

Is there a way to search webelement on a main window first, if not found, then start searching inside iframes?

Requirement: Bydefault, search for webelement on main window, if found perform action else search for webelement inside iframes and perform required action
Selenium 3.141
'''
WebElement el = driver.findElement(By.xpath("//*[contains(text(),'here')]"));
boolean displayFlag = el.isDisplayed();
if(displayFlag == true)
{
sysout("element available in main window")
el.click();
}
else
{
for(int f=0;f<10;f++)
{
sysout("element available in frameset")
switchToFrame(frameName[f]);
el.click();
System.out.println("Webelement not displayed");
}
}
'''
My script is failing at first line itself. It is trying to find element in main window but element is actually available in iframe.
But the requirement is to search first in main window and then only navigate to iframes. How to handle such usecase?
Any suggestion would be helpful? Thank you.
Yes, you can write a loop to go through all the iframes if the element not present in the main window.
Java Implementation:
if (driver.findElements(By.xpath("xpath goes here").size()==0){
int size = driver.findElements(By.tagName("iframe")).size();
for(int iFrameCounter=0; iFrameCounter<=size; iFrameCounter++){
driver.switchTo().frame(iFrameCounter);
if (driver.findElements(By.xpath("xpath goes here").size()>0){
System.out.println("found the element in iframe:" + Integer.toString(iFrameCounter));
// perform the actions on element here
}
driver.switchTo().defaultContent();
}
}
Python Implementation
# switching to parent window - added this to make sure always we check on the parent window first
driver.switch_to.default_content()
# check if the elment present in the parent window
if (len(driver.finds_element_by_xpath("xpath goes here"))==0):
# get the number of iframes
iframes = driver.find_elements_by_tag_name("iframe")
# iterate through all iframes to find out which iframe the required element
for iFrameNumber in iframes:
# switching to iframe (based on counter)
driver.switch_to.frame(iFrameNumber+1)
# check if the element present in the iframe
if len(driver.finds_element_by_xpath("xpath goes here")) > 0:
print("found element in iframe :" + str(iFrameNumber+1))
# perform the operation here
driver.switch_to.default_content()

innerHTML not getting values Selenium Java

Purpose: My code should get the all the links that are available under a drop down menu. It should print all those links under that specific menu.
Site used for testing: http://test1.absofttrainings.com and the specific menu option is Test Pages.
Question/Problem: The code is not printing 2 values that I am expecting, there are 2 links under Test Pages.
Code:
WebDriver driver= new FirefoxDriver();
driver.get("http://test1.absofttrainings.com/#");
//Step1: Create a List of WebElements to put all the links
// the //a will give me all the links associated
List<WebElement> drop_downs= driver.findElements(By.xpath("//a[contains(text(), 'Test Pages')]//a"));
for(int i=0;i<drop_downs.size(); i++){
WebElement e= drop_downs.get(i);
String text=e.getAttribute("innerHTML");
System.out.println("Links are " + text);
}
Thanks in advance for your time.
Code snippet
//find all the links of sibling(s) of the 'Test Pages'
List<WebElement> drop_downs= driver.findElements(By.xpath("//*[contains(text(), 'Test Pages')]/following-sibling::*//a"));
for(WebElement links : drop_downs){
System.out.println(links.getAttribute("innerHTML"));
}

Selenium "Element not found" due to incorrect XPath expression

I am completely new to Selenium and XPath. Today is the first time I am trying to execute a simple script using Selenium RC. Please find the code below.
package com.rcdemo;
import org.junit.Test;
import org.openqa.selenium.By;
import com.thoughtworks.selenium.DefaultSelenium;
import com.thoughtworks.selenium.Selenium;
public class MathTest {
#SuppressWarnings("deprecation")
public static void main(String[] args) throws InterruptedException {
// Instatiate the RC Server
Selenium selenium = new DefaultSelenium("localhost", 4444 , "*firefox C:/Program Files (x86)/Mozilla Firefox/firefox.exe", "http://www.calculator.net");
selenium.start(); // Start
selenium.open("/"); // Open the URL
selenium.windowMaximize();
// Click on Link Math Calculator
selenium.click("xpath=.//*[#id='menu']/div[3]/a");
Thread.sleep(4500); // Wait for page load
// Click on Link Percent Calculator
selenium.click("xpath=//*[#id='content']/ul/li[3]/a");
Thread.sleep(4000); // Wait for page load
// Focus on text Box
selenium.focus("name=cpar1");
// Enter a value in Text box 1
selenium.type("css=input[name=\"cpar1\"]", "10");
// Enter a value in Text box 2
selenium.focus("name=cpar2");
selenium.type("css=input[name=\"cpar2\"]", "50");
// Click the Calculate button
selenium.click("xpath=.//*[#id='content']/table/tbody/tr/td[2]/input");
// Verify if the result is 5
String result = selenium.getText("//*[#id='content']/p[2]/span/font/b");
System.out.println(result);
if (result == "5") {
System.out.println("Pass");
} else {
System.out.println("Fail");
}
}
}
The issue is when executing the above code, an exception is happening at the getText() line. I copied that XPath from the developer tools of Google Chrome. Even when I checked manually once, the same XPath expression is showing. I have tried to find the solution for this from today morning. How can I get Selenium to find the element?
PS: In the result variable I have to capture the result after a calculation. For example, 10 % 50 = 5. This 5 I need to capture.
You need to wait for "Result" to get populated.
Here is the updated code snippet. It should work for you:
// Add this line
if (!selenium.isElementPresent("//*[#id='content']/p[2]/span/font/b"))
{
Thread.sleep(2000);
}
// Verify if the result is 5
String result = selenium.getText("//*[#id='content']/p[2]/span/font/b");
System.out.println(result);
// Update this line
if (result.trim().equals("5"))
{
System.out.println("Pass");
}
else
{
System.out.println("Fail");
}
And you need to use the .equals method to compare the two string values.
Note - A better approach is to replace Thread.sleep with dynamic wait methods, like waitForPageToLoad, waitForElementPresent (custom methods), etc.

How to switch between frames in Selenium WebDriver using Java

I am using java with WebDriver.I have to switch between two frames. I have recorded the test case in selenium IDE and in that I got the values as selectFrame relative=top select Frame=middle Frame
But there is a problem it is not able to recognize the relative=top and middleFrame. How can I solve this problem in Selenium WebDriver with Java?
WebDriver's driver.switchTo().frame() method takes one of the three possible arguments:
A number.
Select a frame by its (zero-based) index. That is, if a page has three
frames, the first frame would be at index 0, the second at index 1
and the third at index 2. Once the frame has been selected, all
subsequent calls on the WebDriver interface are made to that frame.
A name or ID.
Select a frame by its name or ID. Frames located by matching name
attributes are always given precedence over those matched by ID.
A previously found WebElement.
Select a frame using its previously located WebElement.
Get the frame by it's id/name or locate it by driver.findElement() and you'll be good.
to switchto a frame:
driver.switchTo.frame("Frame_ID");
to switch to the default again.
driver.switchTo().defaultContent();
First you have to locate the frame id and define it in a WebElement
For ex:- WebElement fr = driver.findElementById("id");
Then switch to the frame using this code:- driver.switchTo().frame("Frame_ID");
An example script:-
WebElement fr = driver.findElementById("theIframe");
driver.switchTo().frame(fr);
Then to move out of frame use:- driver.switchTo().defaultContent();
You can also use:
driver.switch_to.frame(0)
(0) being the first iframe on the html.
to switch back to the default content:
driver.switch_to.default_content()
Need to make sure once switched into a frame, need to switch back to default content for accessing webelements in another frames. As Webdriver tend to find the new frame inside the current frame.
driver.switchTo().defaultContent()
There is also possibility to use WebDriverWait with ExpectedConditions (to make sure that Frame will be available).
With string as parameter
(new WebDriverWait(driver, 5)).until(ExpectedConditions.frameToBeAvailableAndSwitchToIt("frame-name"));
With locator as a parameter
(new WebDriverWait(driver, 5)).until(ExpectedConditions.frameToBeAvailableAndSwitchToIt(By.id("frame-id")));
More info can be found here
This code is in groovy, so most likely you will need to do some rework. The first param is a url, the second is a counter to limit the tries.
public boolean selectWindow(window, maxTries) {
def handles
int tries = 0
while (true) {
try {
handles = driver.getWindowHandles().toArray()
for (int a = handles.size() - 1; a >= 0 ; a--) { // Backwards is faster with FF since it requires two windows
try {
Log.logger.info("Attempting to select window: " + window)
driver.switchTo().window(handles[a]);
if (driver.getCurrentUrl().equals(window))
return true;
else {
Thread.sleep(2000)
tries++
}
if (tries > maxTries) {
Log.logger.warn("Cannot select page")
return false
}
} catch (Exception ex) {
Thread.sleep(2000)
tries++
}
}
} catch (Exception ex2) {
Thread.sleep(2000)
tries++
}
}
return false;
}

Categories