| // <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; |
| }; |
| } |
| |
| } |