blob: 7bf5985d01a37bb4bb7488e9a12fce7156c33f95 [file] [log] [blame] [edit]
// <copyright file="AlertsTest.cs" company="Selenium Committers">
// 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.
// </copyright>
using NUnit.Framework;
using OpenQA.Selenium.Environment;
using System;
using System.Collections.Generic;
namespace OpenQA.Selenium;
[TestFixture]
public class AlertsTest : DriverTestFixture
{
[Test]
public void ShouldBeAbleToOverrideTheWindowAlertMethod()
{
driver.Url = CreateAlertPage("cheese");
((IJavaScriptExecutor)driver).ExecuteScript(
"window.alert = function(msg) { document.getElementById('text').innerHTML = msg; }");
driver.FindElement(By.Id("alert")).Click();
}
[Test]
public void ShouldAllowUsersToAcceptAnAlertManually()
{
driver.Url = CreateAlertPage("cheese");
driver.FindElement(By.Id("alert")).Click();
IAlert alert = WaitFor<IAlert>(AlertToBePresent, "No alert found");
alert.Accept();
// If we can perform any action, we're good to go
Assert.That(driver.Title, Is.EqualTo("Testing Alerts"));
}
[Test]
public void ShouldThrowArgumentNullExceptionWhenKeysNull()
{
driver.Url = CreateAlertPage("cheese");
driver.FindElement(By.Id("alert")).Click();
IAlert alert = WaitFor<IAlert>(AlertToBePresent, "No alert found");
try
{
Assert.That(
() => alert.SendKeys(null),
Throws.ArgumentNullException);
}
finally
{
alert.Accept();
}
}
[Test]
public void ShouldAllowUsersToAcceptAnAlertWithNoTextManually()
{
driver.Url = CreateAlertPage("");
driver.FindElement(By.Id("alert")).Click();
IAlert alert = WaitFor<IAlert>(AlertToBePresent, "No alert found");
alert.Accept();
// If we can perform any action, we're good to go
Assert.That(driver.Title, Is.EqualTo("Testing Alerts"));
}
[Test]
public void ShouldAllowUsersToDismissAnAlertManually()
{
driver.Url = CreateAlertPage("cheese");
driver.FindElement(By.Id("alert")).Click();
IAlert alert = WaitFor<IAlert>(AlertToBePresent, "No alert found");
alert.Dismiss();
// If we can perform any action, we're good to go
Assert.That(driver.Title, Is.EqualTo("Testing Alerts"));
}
[Test]
public void ShouldAllowAUserToAcceptAPrompt()
{
driver.Url = CreatePromptPage(null);
driver.FindElement(By.Id("prompt")).Click();
IAlert alert = WaitFor<IAlert>(AlertToBePresent, "No alert found");
alert.Accept();
// If we can perform any action, we're good to go
Assert.That(driver.Title, Is.EqualTo("Testing Prompt"));
}
[Test]
public void ShouldAllowAUserToDismissAPrompt()
{
driver.Url = CreatePromptPage(null);
driver.FindElement(By.Id("prompt")).Click();
IAlert alert = WaitFor<IAlert>(AlertToBePresent, "No alert found");
alert.Dismiss();
// If we can perform any action, we're good to go
Assert.That(driver.Title, Is.EqualTo("Testing Prompt"));
}
[Test]
public void ShouldAllowAUserToSetTheValueOfAPrompt()
{
driver.Url = CreatePromptPage(null);
driver.FindElement(By.Id("prompt")).Click();
IAlert alert = WaitFor<IAlert>(AlertToBePresent, "No alert found");
alert.SendKeys("cheese");
alert.Accept();
string result = driver.FindElement(By.Id("text")).Text;
Assert.That(result, Is.EqualTo("cheese"));
}
[Test]
public void SettingTheValueOfAnAlertThrows()
{
driver.Url = CreateAlertPage("cheese");
driver.FindElement(By.Id("alert")).Click();
IAlert alert = WaitFor<IAlert>(AlertToBePresent, "No alert found");
try
{
Assert.That(
() => alert.SendKeys("cheese"),
Throws.TypeOf<ElementNotInteractableException>());
}
finally
{
alert.Accept();
}
}
[Test]
public void ShouldAllowTheUserToGetTheTextOfAnAlert()
{
driver.Url = CreateAlertPage("cheese");
driver.FindElement(By.Id("alert")).Click();
IAlert alert = WaitFor<IAlert>(AlertToBePresent, "No alert found");
string value = alert.Text;
alert.Accept();
Assert.That(value, Is.EqualTo("cheese"));
}
[Test]
public void ShouldAllowTheUserToGetTheTextOfAPrompt()
{
driver.Url = CreatePromptPage(null);
driver.FindElement(By.Id("prompt")).Click();
IAlert alert = WaitFor<IAlert>(AlertToBePresent, "No alert found");
string value = alert.Text;
alert.Accept();
Assert.That(value, Is.EqualTo("Enter something"));
}
[Test]
public void AlertShouldNotAllowAdditionalCommandsIfDismissed()
{
driver.Url = CreateAlertPage("cheese");
driver.FindElement(By.Id("alert")).Click();
IAlert alert = WaitFor<IAlert>(AlertToBePresent, "No alert found");
alert.Dismiss();
Assert.That(
() => alert.Text,
Throws.TypeOf<NoAlertPresentException>());
}
[Test]
public void ShouldAllowUsersToAcceptAnAlertInAFrame()
{
string iframe = EnvironmentManager.Instance.UrlBuilder.CreateInlinePage(new InlinePage()
.WithBody("<a href='#' id='alertInFrame' onclick='alert(\"framed cheese\");'>click me</a>"));
driver.Url = EnvironmentManager.Instance.UrlBuilder.CreateInlinePage(new InlinePage()
.WithTitle("Testing Alerts")
.WithBody(String.Format("<iframe src='{0}' name='iframeWithAlert'></iframe>", iframe)));
driver.SwitchTo().Frame("iframeWithAlert");
driver.FindElement(By.Id("alertInFrame")).Click();
IAlert alert = WaitFor<IAlert>(AlertToBePresent, "No alert found");
alert.Accept();
// If we can perform any action, we're good to go
Assert.That(driver.Title, Is.EqualTo("Testing Alerts"));
}
[Test]
public void ShouldAllowUsersToAcceptAnAlertInANestedFrame()
{
string iframe = EnvironmentManager.Instance.UrlBuilder.CreateInlinePage(new InlinePage()
.WithBody("<a href='#' id='alertInFrame' onclick='alert(\"framed cheese\");'>click me</a>"));
string iframe2 = EnvironmentManager.Instance.UrlBuilder.CreateInlinePage(new InlinePage()
.WithBody(string.Format("<iframe src='{0}' name='iframeWithAlert'></iframe>", iframe)));
driver.Url = EnvironmentManager.Instance.UrlBuilder.CreateInlinePage(new InlinePage()
.WithTitle("Testing Alerts")
.WithBody(string.Format("<iframe src='{0}' name='iframeWithIframe'></iframe>", iframe2)));
driver.SwitchTo().Frame("iframeWithIframe").SwitchTo().Frame("iframeWithAlert");
driver.FindElement(By.Id("alertInFrame")).Click();
IAlert alert = WaitFor<IAlert>(AlertToBePresent, "No alert found");
alert.Accept();
// If we can perform any action, we're good to go
Assert.That(driver.Title, Is.EqualTo("Testing Alerts"));
}
[Test]
public void SwitchingToMissingAlertThrows()
{
driver.Url = CreateAlertPage("cheese");
Assert.That(
() => AlertToBePresent(),
Throws.TypeOf<NoAlertPresentException>());
}
[Test]
[IgnoreBrowser(Browser.IE, "Edge in IE Mode does not properly handle multiple windows")]
public void SwitchingToMissingAlertInAClosedWindowThrows()
{
string blank = EnvironmentManager.Instance.UrlBuilder.CreateInlinePage(new InlinePage());
driver.Url = EnvironmentManager.Instance.UrlBuilder.CreateInlinePage(new InlinePage()
.WithBody(String.Format(
"<a id='open-new-window' href='{0}' target='newwindow'>open new window</a>", blank)));
string mainWindow = driver.CurrentWindowHandle;
try
{
driver.FindElement(By.Id("open-new-window")).Click();
WaitFor(WindowHandleCountToBe(2), "Window count was not 2");
WaitFor(WindowWithName("newwindow"), "Could not find window with name 'newwindow'");
driver.Close();
WaitFor(WindowHandleCountToBe(1), "Window count was not 1");
Assert.That(
() => AlertToBePresent().Accept(),
Throws.TypeOf<NoSuchWindowException>());
}
finally
{
driver.SwitchTo().Window(mainWindow);
WaitFor(ElementTextToEqual(driver.FindElement(By.Id("open-new-window")), "open new window"), "Could not find element with text 'open new window'");
}
}
[Test]
public void PromptShouldUseDefaultValueIfNoKeysSent()
{
driver.Url = CreatePromptPage("This is a default value");
driver.FindElement(By.Id("prompt")).Click();
IAlert alert = WaitFor<IAlert>(AlertToBePresent, "No alert found");
alert.Accept();
IWebElement element = driver.FindElement(By.Id("text"));
WaitFor(ElementTextToEqual(element, "This is a default value"), "Element text was not 'This is a default value'");
Assert.That(element.Text, Is.EqualTo("This is a default value"));
}
[Test]
public void PromptShouldHaveNullValueIfDismissed()
{
driver.Url = CreatePromptPage("This is a default value");
driver.FindElement(By.Id("prompt")).Click();
IAlert alert = WaitFor<IAlert>(AlertToBePresent, "No alert found");
alert.Dismiss();
IWebElement element = driver.FindElement(By.Id("text"));
WaitFor(ElementTextToEqual(element, "null"), "Element text was not 'null'");
Assert.That(element.Text, Is.EqualTo("null"));
}
[Test]
[IgnoreBrowser(Browser.Remote)]
public void HandlesTwoAlertsFromOneInteraction()
{
driver.Url = EnvironmentManager.Instance.UrlBuilder.CreateInlinePage(new InlinePage()
.WithScripts(
"""
function setInnerText(id, value) {
document.getElementById(id).innerHTML = '<p>' + value + '</p>';
}
function displayTwoPrompts() {
setInnerText('text1', prompt('First'));
setInnerText('text2', prompt('Second'));
}
""")
.WithBody(
"""
<a href='#' id='double-prompt' onclick='displayTwoPrompts();'>click me</a>
<div id='text1'></div>
<div id='text2'></div>
"""));
driver.FindElement(By.Id("double-prompt")).Click();
IAlert alert1 = WaitFor<IAlert>(AlertToBePresent, "No alert found");
alert1.SendKeys("brie");
alert1.Accept();
IAlert alert2 = WaitFor<IAlert>(AlertToBePresent, "No alert found");
alert2.SendKeys("cheddar");
alert2.Accept();
IWebElement element1 = driver.FindElement(By.Id("text1"));
WaitFor(ElementTextToEqual(element1, "brie"), "Element text was not 'brie'");
Assert.That(element1.Text, Is.EqualTo("brie"));
IWebElement element2 = driver.FindElement(By.Id("text2"));
WaitFor(ElementTextToEqual(element2, "cheddar"), "Element text was not 'cheddar'");
Assert.That(element2.Text, Is.EqualTo("cheddar"));
}
[Test]
public void ShouldHandleAlertOnPageLoad()
{
string pageWithOnLoad = EnvironmentManager.Instance.UrlBuilder.CreateInlinePage(new InlinePage()
.WithOnLoad("""javascript:alert("onload")""")
.WithBody("<p>Page with onload event handler</p>"));
driver.Url = EnvironmentManager.Instance.UrlBuilder.CreateInlinePage(new InlinePage()
.WithBody(string.Format("<a id='open-page-with-onload-alert' href='{0}'>open new page</a>", pageWithOnLoad)));
driver.FindElement(By.Id("open-page-with-onload-alert")).Click();
IAlert alert = WaitFor<IAlert>(AlertToBePresent, "No alert found");
string value = alert.Text;
alert.Accept();
Assert.That(value, Is.EqualTo("onload"));
IWebElement element = driver.FindElement(By.TagName("p"));
WaitFor(ElementTextToEqual(element, "Page with onload event handler"), "Element text was not 'Page with onload event handler'");
}
[Test]
public void ShouldHandleAlertOnPageLoadUsingGet()
{
driver.Url = EnvironmentManager.Instance.UrlBuilder.CreateInlinePage(new InlinePage()
.WithOnLoad("javascript:alert(\"onload\")")
.WithBody("<p>Page with onload event handler</p>"));
IAlert alert = WaitFor<IAlert>(AlertToBePresent, "No alert found");
string value = alert.Text;
alert.Accept();
Assert.That(value, Is.EqualTo("onload"));
WaitFor(ElementTextToEqual(driver.FindElement(By.TagName("p")), "Page with onload event handler"), "Could not find element with text 'Page with onload event handler'");
}
[Test]
[IgnoreBrowser(Browser.IE, "Edge in IE Mode does not properly handle multiple windows")]
[IgnoreBrowser(Browser.Chrome, "Test with onLoad alert hangs Chrome.")]
[IgnoreBrowser(Browser.Edge, "Test with onLoad alert hangs Edge.")]
[IgnoreBrowser(Browser.Safari, "Safari driver does not allow commands in any window when an alert is active")]
public void ShouldNotHandleAlertInAnotherWindow()
{
string pageWithOnLoad = EnvironmentManager.Instance.UrlBuilder.CreateInlinePage(new InlinePage()
.WithOnLoad("javascript:alert(\"onload\")")
.WithBody("<p>Page with onload event handler</p>"));
driver.Url = EnvironmentManager.Instance.UrlBuilder.CreateInlinePage(new InlinePage()
.WithBody(string.Format(
"<a id='open-new-window' href='{0}' target='newwindow'>open new window</a>", pageWithOnLoad)));
string mainWindow = driver.CurrentWindowHandle;
string onloadWindow = null;
try
{
driver.FindElement(By.Id("open-new-window")).Click();
List<String> allWindows = new List<string>(driver.WindowHandles);
allWindows.Remove(mainWindow);
Assert.That(allWindows, Has.One.Items);
onloadWindow = allWindows[0];
Assert.That(() =>
{
IWebElement el = driver.FindElement(By.Id("open-new-window"));
WaitFor<IAlert>(AlertToBePresent, TimeSpan.FromSeconds(5), "No alert found");
},
Throws.TypeOf<WebDriverException>());
}
finally
{
driver.SwitchTo().Window(onloadWindow);
WaitFor<IAlert>(AlertToBePresent, "No alert found").Dismiss();
driver.Close();
driver.SwitchTo().Window(mainWindow);
WaitFor(ElementTextToEqual(driver.FindElement(By.Id("open-new-window")), "open new window"), "Could not find element with text 'open new window'");
}
}
[Test]
[IgnoreBrowser(Browser.Firefox, "Driver chooses not to return text from unhandled alert")]
public void IncludesAlertTextInUnhandledAlertException()
{
driver.Url = CreateAlertPage("cheese");
driver.FindElement(By.Id("alert")).Click();
WaitFor<IAlert>(AlertToBePresent, "No alert found");
Assert.That(
() => driver.Title,
Throws.TypeOf<UnhandledAlertException>().With.Property(nameof(UnhandledAlertException.AlertText)).EqualTo("cheese"));
}
[Test]
[NeedsFreshDriver(IsCreatedAfterTest = true)]
public void CanQuitWhenAnAlertIsPresent()
{
driver.Url = CreateAlertPage("cheese");
driver.FindElement(By.Id("alert")).Click();
IAlert alert = WaitFor<IAlert>(AlertToBePresent, "No alert found");
EnvironmentManager.Instance.CloseCurrentDriver();
}
[Test]
public void ShouldHandleAlertOnFormSubmit()
{
driver.Url = EnvironmentManager.Instance.UrlBuilder.CreateInlinePage(new InlinePage()
.WithTitle("Testing Alerts").
WithBody("<form id='theForm' action='javascript:alert(\"Tasty cheese\");'>",
"<input id='unused' type='submit' value='Submit'>",
"</form>"));
IWebElement element = driver.FindElement(By.Id("theForm"));
element.Submit();
IAlert alert = WaitFor<IAlert>(AlertToBePresent, "No alert found");
string text = alert.Text;
alert.Accept();
Assert.That(text, Is.EqualTo("Tasty cheese"));
Assert.That(driver.Title, Is.EqualTo("Testing Alerts"));
}
private IAlert AlertToBePresent()
{
return driver.SwitchTo().Alert();
}
private string CreateAlertPage(string alertText)
{
return EnvironmentManager.Instance.UrlBuilder.CreateInlinePage(new InlinePage()
.WithTitle("Testing Alerts")
.WithBody("<a href='#' id='alert' onclick='alert(\"" + alertText + "\");'>click me</a>"));
}
private string CreatePromptPage(string defaultText)
{
return EnvironmentManager.Instance.UrlBuilder.CreateInlinePage(new InlinePage()
.WithTitle("Testing Prompt")
.WithScripts(
"function setInnerText(id, value) {",
" document.getElementById(id).innerHTML = '<p>' + value + '</p>';",
"}",
defaultText == null
? "function displayPrompt() { setInnerText('text', prompt('Enter something')); }"
: "function displayPrompt() { setInnerText('text', prompt('Enter something', '" + defaultText + "')); }")
.WithBody(
"<a href='#' id='prompt' onclick='displayPrompt();'>click me</a>",
"<div id='text'>acceptor</div>"));
}
private void SetSimpleOnBeforeUnload(string returnText)
{
((IJavaScriptExecutor)driver).ExecuteScript(
"var returnText = arguments[0]; window.onbeforeunload = function() { return returnText; }",
returnText);
}
private Func<IWebElement> ElementToBePresent(By locator)
{
return () =>
{
try
{
return driver.FindElement(By.Id("open-page-with-onunload-alert"));
}
catch (NoSuchElementException)
{
return null;
}
};
}
private Func<bool> ElementTextToEqual(IWebElement element, string text)
{
return () =>
{
return element.Text == text;
};
}
private Func<bool> WindowWithName(string name)
{
return () =>
{
try
{
driver.SwitchTo().Window(name);
return true;
}
catch (NoSuchWindowException)
{
return false;
}
};
}
private Func<bool> WindowHandleCountToBe(int count)
{
return () =>
{
return driver.WindowHandles.Count == count;
};
}
}