blob: 04f91d8450184f66bdb391c7f94675352db13b81 [file] [log] [blame]
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
package org.openqa.selenium;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import static org.openqa.selenium.support.ui.ExpectedConditions.frameToBeAvailableAndSwitchToIt;
import static org.openqa.selenium.support.ui.ExpectedConditions.not;
import static org.openqa.selenium.support.ui.ExpectedConditions.presenceOfElementLocated;
import static org.openqa.selenium.support.ui.ExpectedConditions.textToBe;
import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.testing.drivers.Browser.CHROME;
import static org.openqa.selenium.testing.drivers.Browser.EDGE;
import static org.openqa.selenium.testing.drivers.Browser.IE;
import static org.openqa.selenium.testing.drivers.Browser.SAFARI;
import java.util.Random;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Timeout;
import org.openqa.selenium.testing.Ignore;
import org.openqa.selenium.testing.JupiterTestBase;
import org.openqa.selenium.testing.NotYetImplemented;
class FrameSwitchingTest extends JupiterTestBase {
private Random random;
@AfterEach
public void tearDown() {
try {
driver.switchTo().defaultContent();
} catch (Exception e) {
// May happen if the driver went away.
}
}
// ----------------------------------------------------------------------------------------------
//
// Tests that WebDriver doesn't do anything fishy when it navigates to a page with frames.
//
// ----------------------------------------------------------------------------------------------
@Test
void testShouldAlwaysFocusOnTheTopMostFrameAfterANavigationEvent() {
driver.get(pages.framesetPage);
driver.findElement(By.tagName("frameset")); // Test passes if this does not throw.
}
@Test
void testShouldNotAutomaticallySwitchFocusToAnIFrameWhenAPageContainingThemIsLoaded() {
driver.get(pages.iframePage);
driver.findElement(By.id("iframe_page_heading"));
}
@Test
@Timeout(10)
public void testShouldOpenPageWithBrokenFrameset() {
driver.get(appServer.whereIs("framesetPage3.html"));
WebElement frame1 = driver.findElement(By.id("first"));
driver.switchTo().frame(frame1);
driver.switchTo().defaultContent();
WebElement frame2 = driver.findElement(By.id("second"));
try {
driver.switchTo().frame(frame2);
} catch (WebDriverException e) {
// IE9 can not switch to this broken frame - it has no window.
}
}
// ----------------------------------------------------------------------------------------------
//
// Tests that WebDriver can switch to frames as expected.
//
// ----------------------------------------------------------------------------------------------
@Test
void testShouldBeAbleToSwitchToAFrameByItsIndex() {
driver.get(pages.framesetPage);
driver.switchTo().frame(1);
assertThat(driver.findElement(By.id("pageNumber")).getText()).isEqualTo("2");
}
@Test
void testShouldBeAbleToSwitchToAnIframeByItsIndex() {
driver.get(pages.iframePage);
driver.switchTo().frame(0);
assertThat(driver.findElement(By.name("id-name1")).getAttribute("value")).isEqualTo("name");
}
@Test
void testShouldBeAbleToSwitchToAFrameByItsName() {
driver.get(pages.framesetPage);
driver.switchTo().frame("fourth");
assertThat(driver.findElement(By.tagName("frame")).getAttribute("name")).isEqualTo("child1");
}
@Test
void testShouldBeAbleToSwitchToAnIframeByItsName() {
driver.get(pages.iframePage);
driver.switchTo().frame("iframe1-name");
assertThat(driver.findElement(By.name("id-name1")).getAttribute("value")).isEqualTo("name");
}
@Test
void testShouldBeAbleToSwitchToAFrameByItsID() {
driver.get(pages.framesetPage);
driver.switchTo().frame("fifth");
assertThat(driver.findElement(By.name("windowOne")).getText()).isEqualTo("Open new window");
}
@Test
void testShouldBeAbleToSwitchToAnIframeByItsID() {
driver.get(pages.iframePage);
driver.switchTo().frame("iframe1");
assertThat(driver.findElement(By.name("id-name1")).getAttribute("value")).isEqualTo("name");
}
@Test
void testShouldBeAbleToSwitchToFrameWithNameContainingDot() {
driver.get(pages.framesetPage);
driver.switchTo().frame("sixth.iframe1");
assertThat(driver.findElement(By.tagName("body")).getText()).contains("Page number 3");
}
@Test
void testShouldBeAbleToSwitchToAFrameUsingAPreviouslyLocatedWebElement() {
driver.get(pages.framesetPage);
WebElement frame = driver.findElement(By.tagName("frame"));
driver.switchTo().frame(frame);
assertThat(driver.findElement(By.id("pageNumber")).getText()).isEqualTo("1");
}
@Test
void testShouldBeAbleToSwitchToAnIFrameUsingAPreviouslyLocatedWebElement() {
driver.get(pages.iframePage);
WebElement frame = driver.findElement(By.tagName("iframe"));
driver.switchTo().frame(frame);
WebElement element = driver.findElement(By.name("id-name1"));
assertThat(element.getAttribute("value")).isEqualTo("name");
}
@Test
void testShouldEnsureElementIsAFrameBeforeSwitching() {
driver.get(pages.framesetPage);
WebElement frame = driver.findElement(By.tagName("frameset"));
assertThatExceptionOfType(NoSuchFrameException.class)
.isThrownBy(() -> driver.switchTo().frame(frame));
}
@Test
void testFrameSearchesShouldBeRelativeToTheCurrentlySelectedFrame() {
driver.get(pages.framesetPage);
driver.switchTo().frame("second");
assertThat(driver.findElement(By.id("pageNumber")).getText()).isEqualTo("2");
assertThatExceptionOfType(NoSuchFrameException.class)
.isThrownBy(() -> driver.switchTo().frame("third"));
driver.switchTo().defaultContent();
driver.switchTo().frame("third");
assertThatExceptionOfType(NoSuchFrameException.class)
.isThrownBy(() -> driver.switchTo().frame("second"));
driver.switchTo().defaultContent();
driver.switchTo().frame("second");
assertThat(driver.findElement(By.id("pageNumber")).getText()).isEqualTo("2");
}
@Test
void testShouldSelectChildFramesByChainedCalls() {
driver.get(pages.framesetPage);
driver.switchTo().frame("fourth").switchTo().frame("child2");
assertThat(driver.findElement(By.id("pageNumber")).getText()).isEqualTo("11");
}
@Test
void testShouldThrowFrameNotFoundExceptionLookingUpSubFramesWithSuperFrameNames() {
driver.get(pages.framesetPage);
driver.switchTo().frame("fourth");
assertThatExceptionOfType(NoSuchFrameException.class)
.isThrownBy(() -> driver.switchTo().frame("second"));
}
@Test
void testShouldThrowAnExceptionWhenAFrameCannotBeFound() {
driver.get(pages.xhtmlTestPage);
assertThatExceptionOfType(NoSuchFrameException.class)
.isThrownBy(() -> driver.switchTo().frame("Nothing here"));
}
@Test
void testShouldThrowAnExceptionWhenAFrameCannotBeFoundByIndex() {
driver.get(pages.xhtmlTestPage);
assertThatExceptionOfType(NoSuchFrameException.class)
.isThrownBy(() -> driver.switchTo().frame(27));
}
@Test
void testShouldBeAbleToSwitchToParentFrame() {
driver.get(pages.framesetPage);
driver.switchTo().frame("fourth").switchTo().parentFrame().switchTo().frame("first");
assertThat(driver.findElement(By.id("pageNumber")).getText()).isEqualTo("1");
}
@Test
@NotYetImplemented(SAFARI)
public void testShouldBeAbleToSwitchToParentFrameFromASecondLevelFrame() {
driver.get(pages.framesetPage);
driver
.switchTo()
.frame("fourth")
.switchTo()
.frame("child1")
.switchTo()
.parentFrame()
.switchTo()
.frame("child2");
assertThat(driver.findElement(By.id("pageNumber")).getText()).isEqualTo("11");
}
@Test
void testSwitchingToParentFrameFromDefaultContextIsNoOp() {
driver.get(pages.xhtmlTestPage);
driver.switchTo().parentFrame();
assertThat(driver.getTitle()).isEqualTo("XHTML Test Page");
}
@Test
void testShouldBeAbleToSwitchToParentFromAnIframe() {
driver.get(pages.iframePage);
driver.switchTo().frame(0);
driver.switchTo().parentFrame();
driver.findElement(By.id("iframe_page_heading"));
}
// ----------------------------------------------------------------------------------------------
//
// General frame handling behavior tests
//
// ----------------------------------------------------------------------------------------------
@Test
void testShouldContinueToReferToTheSameFrameOnceItHasBeenSelected() {
driver.get(pages.framesetPage);
driver.switchTo().frame(2);
WebElement checkbox = driver.findElement(By.xpath("//input[@name='checky']"));
checkbox.click();
checkbox.submit();
wait.until(textToBe(By.xpath("//p"), "Success!"));
}
@Test
@NotYetImplemented(SAFARI)
public void testShouldFocusOnTheReplacementWhenAFrameFollowsALinkToA_TopTargetedPage() {
driver.get(pages.framesetPage);
driver.switchTo().frame(0);
driver.findElement(By.linkText("top")).click();
String expectedTitle = "XHTML Test Page";
wait.until(titleIs(expectedTitle));
}
@Test
void testShouldAllowAUserToSwitchFromAnIframeBackToTheMainContentOfThePage() {
driver.get(pages.iframePage);
driver.switchTo().frame(0);
driver.switchTo().defaultContent();
driver.findElement(By.id("iframe_page_heading"));
}
@Test
void testShouldAllowTheUserToSwitchToAnIFrameAndRemainFocusedOnIt() {
driver.get(pages.iframePage);
driver.switchTo().frame(0);
driver.findElement(By.id("submitButton")).click();
assertThat(getTextOfGreetingElement()).isEqualTo("Success!");
}
public String getTextOfGreetingElement() {
return wait.until(presenceOfElementLocated(By.id("greeting"))).getText();
}
@Test
void testShouldBeAbleToClickInAFrame() {
driver.get(pages.framesetPage);
driver.switchTo().frame("third");
// This should replace frame "third" ...
driver.findElement(By.id("submitButton")).click();
// driver should still be focused on frame "third" ...
assertThat(getTextOfGreetingElement()).isEqualTo("Success!");
// Make sure it was really frame "third" which was replaced ...
driver.switchTo().defaultContent().switchTo().frame("third");
assertThat(getTextOfGreetingElement()).isEqualTo("Success!");
}
@Test
void testShouldBeAbleToClickInAFrameThatRewritesTopWindowLocation() {
driver.get(appServer.whereIs("click_tests/issue5237.html"));
driver.switchTo().frame("search");
driver.findElement(By.id("submit")).click();
driver.switchTo().defaultContent();
wait.until(titleIs("Target page for issue 5237"));
}
@Test
void testShouldBeAbleToClickInASubFrame() {
driver.get(pages.framesetPage);
driver.switchTo().frame("sixth").switchTo().frame("iframe1");
// This should replace frame "iframe1" inside frame "sixth" ...
driver.findElement(By.id("submitButton")).click();
// driver should still be focused on frame "iframe1" inside frame "sixth" ...
assertThat(getTextOfGreetingElement()).isEqualTo("Success!");
// Make sure it was really frame "iframe1" inside frame "sixth" which was replaced ...
driver.switchTo().defaultContent().switchTo().frame("sixth").switchTo().frame("iframe1");
assertThat(driver.findElement(By.id("greeting")).getText()).isEqualTo("Success!");
}
@Test
void testShouldBeAbleToFindElementsInIframesByXPath() {
driver.get(pages.iframePage);
driver.switchTo().frame("iframe1");
WebElement element = driver.findElement(By.xpath("//*[@id = 'changeme']"));
assertThat(element).isNotNull();
}
@Test
void testGetCurrentUrlReturnsTopLevelBrowsingContextUrl() {
driver.get(pages.framesetPage);
assertThat(driver.getCurrentUrl()).isEqualTo(pages.framesetPage);
driver.switchTo().frame("second");
assertThat(driver.getCurrentUrl()).isEqualTo(pages.framesetPage);
}
@Test
void testGetCurrentUrlReturnsTopLevelBrowsingContextUrlForIframes() {
driver.get(pages.iframePage);
assertThat(driver.getCurrentUrl()).isEqualTo(pages.iframePage);
driver.switchTo().frame("iframe1");
assertThat(driver.getCurrentUrl()).isEqualTo(pages.iframePage);
}
@Test
@Ignore(SAFARI)
public void testShouldBeAbleToSwitchToTheTopIfTheFrameIsDeletedFromUnderUs() {
driver.get(appServer.whereIs("frame_switching_tests/deletingFrame.html"));
driver.switchTo().frame("iframe1");
WebElement killIframe = driver.findElement(By.id("killIframe"));
killIframe.click();
driver.switchTo().defaultContent();
assertFrameNotPresent("iframe1");
WebElement addIFrame = driver.findElement(By.id("addBackFrame"));
addIFrame.click();
wait.until(presenceOfElementLocated(By.id("iframe1")));
driver.switchTo().frame("iframe1");
wait.until(presenceOfElementLocated(By.id("success")));
}
@Test
@Ignore(SAFARI)
public void testShouldBeAbleToSwitchToTheTopIfTheFrameIsDeletedFromUnderUsWithFrameIndex() {
driver.get(appServer.whereIs("frame_switching_tests/deletingFrame.html"));
int iframe = 0;
wait.until(frameToBeAvailableAndSwitchToIt(iframe));
// we should be in the frame now
WebElement killIframe = driver.findElement(By.id("killIframe"));
killIframe.click();
driver.switchTo().defaultContent();
WebElement addIFrame = driver.findElement(By.id("addBackFrame"));
addIFrame.click();
wait.until(frameToBeAvailableAndSwitchToIt(iframe));
wait.until(presenceOfElementLocated(By.id("success")));
}
@Test
@Ignore(SAFARI)
public void testShouldBeAbleToSwitchToTheTopIfTheFrameIsDeletedFromUnderUsWithWebElement() {
driver.get(appServer.whereIs("frame_switching_tests/deletingFrame.html"));
WebElement iframe = driver.findElement(By.id("iframe1"));
wait.until(frameToBeAvailableAndSwitchToIt(iframe));
// we should be in the frame now
WebElement killIframe = driver.findElement(By.id("killIframe"));
killIframe.click();
driver.switchTo().defaultContent();
WebElement addIFrame = driver.findElement(By.id("addBackFrame"));
addIFrame.click();
iframe = driver.findElement(By.id("iframe1"));
wait.until(frameToBeAvailableAndSwitchToIt(iframe));
wait.until(presenceOfElementLocated(By.id("success")));
}
@Test
@NotYetImplemented(value = CHROME, reason = "Throws NoSuchElementException")
@NotYetImplemented(value = EDGE, reason = "Throws NoSuchElementException")
@Ignore(IE)
@Ignore(SAFARI)
public void testShouldNotBeAbleToDoAnythingTheFrameIsDeletedFromUnderUs() {
driver.get(appServer.whereIs("frame_switching_tests/deletingFrame.html"));
driver.switchTo().frame("iframe1");
driver.findElement(By.id("killIframe")).click();
assertThatExceptionOfType(NoSuchWindowException.class)
.isThrownBy(() -> driver.findElement(By.id("killIframe")));
}
@Test
void testShouldReturnWindowTitleInAFrameset() {
driver.get(pages.framesetPage);
driver.switchTo().frame("third");
assertThat(driver.getTitle()).isEqualTo("Unique title");
}
@Test
void testJavaScriptShouldExecuteInTheContextOfTheCurrentFrame() {
JavascriptExecutor executor = (JavascriptExecutor) driver;
driver.get(pages.framesetPage);
assertThat((Boolean) executor.executeScript("return window == window.top")).isTrue();
driver.switchTo().frame("third");
assertThat((Boolean) executor.executeScript("return window != window.top")).isTrue();
}
@Test
void testShouldNotSwitchMagicallyToTheTopWindow() {
String baseUrl = appServer.whereIs("frame_switching_tests/");
driver.get(baseUrl + "bug4876.html");
driver.switchTo().frame(0);
wait.until(presenceOfElementLocated(By.id("inputText")));
for (int i = 0; i < 20; i++) {
try {
WebElement input = wait.until(presenceOfElementLocated(By.id("inputText")));
WebElement submit = wait.until(presenceOfElementLocated(By.id("submitButton")));
input.clear();
random = new Random();
input.sendKeys("rand" + random.nextInt());
submit.click();
} finally {
String url =
(String) ((JavascriptExecutor) driver).executeScript("return window.location.href");
// IE6 and Chrome add "?"-symbol to the end of the URL
if (url.endsWith("?")) {
url = url.substring(0, url.length() - 1);
}
assertThat(url).isEqualTo(baseUrl + "bug4876_iframe.html");
}
}
}
@Test
void testGetShouldSwitchToDefaultContext() {
driver.get(pages.iframePage);
driver.switchTo().frame(driver.findElement(By.id("iframe1")));
driver.findElement(By.id("cheese")); // Found on formPage.html but not on iframes.html.
driver.get(pages.iframePage); // This must effectively switchTo().defaultContent(), too.
driver.findElement(By.id("iframe1"));
}
private void assertFrameNotPresent(String locator) {
driver.switchTo().defaultContent();
wait.until(not(frameToBeAvailableAndSwitchToIt(locator)));
driver.switchTo().defaultContent();
}
}