0

Hi all I am unable to interact with "Index" on the last line of code the code is working fine for all items except for the nested frames it is giving error as unable to locate element I have tried both xpath and linked text for this still getting this error this is a demo website for test automation practice the error is only for the index in the last line of the code all other parts of the code are working fine.

package sdet;
import org.openqa.selenium.*;
import org.openqa.selenium.By;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import org.openqa.selenium.WebElement;

import java.awt.event.ActionEvent;
import java.time.Duration;
import java.util.*;

public class selenium {

    public static void main(String[] args) throws InterruptedException {
        // TODO Auto-generated method stub
System.setProperty("Pathtochromedriver");
WebDriver driver = new ChromeDriver();
driver.get("https://testpages.herokuapp.com/");
driver.manage().window().maximize();
// Clicking on basic webpages //
driver.findElement(By.id("basicpagetest")).click();
String  Urlnow = driver.getCurrentUrl();
System.out.println("current url is :" +Urlnow );
driver.findElement(By.linkText("Index")).click();
driver.findElement(By.id("elementattributestest")).click();
Thread.sleep(2000);
driver.navigate().forward();
JavascriptExecutor js = (JavascriptExecutor) driver;
js.executeScript("javascript:window.scrollBy(250,350)");
Thread.sleep(2000);
WebElement Addattribute = driver.findElement(By.xpath("//button[@class=\"styled-click-button\"]"));
Actions actions = new Actions(driver);
actions.moveToElement(Addattribute).doubleClick().build().perform();
Thread.sleep(2000);
driver.navigate().forward();
js.executeScript("window.scrollBy(0,-400)");
// Clicking on index here // 
driver.findElement(By.linkText("Index")).click();
driver.findElement(By.id("findbytest")).click();
Thread.sleep(2000);
driver.findElement(By.linkText("Index")).click();
driver.findElement(By.id("tablestest")).click();
Thread.sleep(2000);
driver.findElement(By.linkText("Index")).click();
driver.findElement(By.id("dynamictablestest")).click();
Thread.sleep(2000);
driver.findElement(By.linkText("Index")).click();
driver.findElement(By.id("alerttest")).click();
driver.findElement(By.id("alertexamples")).click();
driver.switchTo().alert().accept();
// Clicking on show confirm box //
driver.findElement(By.id("confirmexample")).click();
Thread.sleep(2000);
driver.switchTo().alert().dismiss();
Thread.sleep(2000);
driver.findElement(By.linkText("Index")).click();
driver.findElement(By.id("fakealerttest")).click();
// Clicking on showalertbox //
driver.findElement(By.id("fakealert")).click();
driver.findElement(By.id("dialog-ok")).click();
// Clicking on modal dialog //
driver.findElement(By.id("modaldialog")).click();
driver.findElement(By.id("dialog-ok")).click();
Thread.sleep(2000);
driver.findElement(By.linkText("Index")).click();
// Clicking on frames test //
driver.findElement(By.id("framestest")).click();
Thread.sleep(4000);
driver.navigate().forward();
driver.findElement(By.linkText("Index")).click();

//driver.findElement(By.id("framestest")).click();
//Thread.sleep(2000);
//driver.findElement(By.linkText("Index")).click();


}

}
Bug Hunter
  • 21
  • 5

3 Answers3

1

As far as on that page Index element is placed in frame, you should use

driver.switchTo().frame("top");

before

driver.findElement(By.linkText("Index")).click();

where top is name attribute of your iframe.

Selenium by default uses top body level context and doesn't see elements in other contexts like iframes or shadow-roots. So to get him to know that you want to search for element in another context, you should change context Selenium is looking into.

And don't forget to switch to defaultContext() back when you returning to body context.

Yaroslavm
  • 1,762
  • 2
  • 7
  • 15
1

Use below line:

driver.switchTo().frame(0);

(0) - being the first frame on the HTML.

So your last 4 lines of code should be as below:

Thread.sleep(4000);
driver.navigate().forward();
driver.switchTo().frame(0);
driver.findElement(By.linkText("Index")).click();

Note: To switch back to default content, below line of code should be used:

driver.switch_to.default_content()
Shawn
  • 4,064
  • 2
  • 11
  • 23
0

Within the website Test Pages For Automating once you click on the link with text as Frames Test Page and navigate to the Nested Frames Example page, the element with text as Index is within a <frame>:

frame


Solution

To click on the element with text as Index you have to:

  • Induce WebDriverWait for the desired frameToBeAvailableAndSwitchToIt.

  • Induce WebDriverWait for the desired elementToBeClickable.

  • You can use either of the following Locator Strategies:

    ChromeOptions options = new ChromeOptions();
    options.addArguments("--start-maximized");
    WebDriver driver = new ChromeDriver(options);
    driver.get("https://testpages.herokuapp.com/styled/index.html");
    new WebDriverWait(driver, Duration.ofSeconds(5)).until(ExpectedConditions.elementToBeClickable(By.id("framestest"))).click();
    new WebDriverWait(driver, Duration.ofSeconds(5)).until(ExpectedConditions.frameToBeAvailableAndSwitchToIt(By.name("top")));
    new WebDriverWait(driver, Duration.ofSeconds(5)).until(ExpectedConditions.elementToBeClickable(By.linkText("Index"))).click();
    

References

You can find a couple of relevant discussions in:

undetected Selenium
  • 183,867
  • 41
  • 278
  • 352