我使用SpecFlow,MSTests进行单元测试和WatiN来驱动浏览器测试我们的Web应用程序。
如果用户提交表单而未填写所有必填字段,则会弹出JavaScript alert
。我试图用WatiN检测这个弹出窗口。触发警报的SpecFlow步骤与断言弹出窗口的SpecFlow步骤不同,因此等待WatiN对话框处理程序不起作用,因为警报已经打开。
示例SpecFlow场景:
Scenario: Form Fields are required
# This step spawns the alert dialog
When I click the "Save and Continue" button
# Test fails here because the alert is already open
Then I should see the validation error alert
When I click the "Save and Continue" button
[When(@"I click the ""(.*)"" button")]
public void WhenIClickTheButton(string buttonText)
{
Button button = BitWeb.Browser.Button(Find.ByValue(buttonText).Or(Find.ByText(buttonText)));
Assert.IsTrue(button.Exists, "No button with text '{0}' was found", buttonText);
button.Click();
browser.WaitForComplete();
}
Then I should see the ... alert
的步骤定义:
[Then(@"I should see the validation error alert")]
public void ThenIShouldSeeTheValidationErrorAlert()
{
var alert = new WatiN.Core.DialogHandlers.AlertDialogHandler();
alert.WaitUntilExists();
StringAssert.Contains(alert.Message, "An error has occurred. Check entire", "The validation error alert was not visible.");
}
对alert.WaitUntilExists();
的调用引发异常:
WatiN.Core.Exceptions.WatiNException:对话框在30秒内无法使用。
当我断言警报对话框可见时,DialogHandler没有找到警报,因为它已经打开。
如何使用WatiN找到已打开的警告对话框?
更新#1:我倾向于使用ScenarioContext.Current
对象的解决方案,我只是不确定如何将所有内容连接在一起以便浏览器不会每次点击按钮时都会等待30秒,以查看是否弹出警告框。
更新#2:经过一些调查后,在一个步骤中单击按钮会导致整个测试框架暂停,直到alert
对话框被解除为止。单击"确定"按钮取消了对话框,允许测试运行器前进到下一步,我断言对话框是可见的 - 鸡蛋或鸡蛋情景。致电button.ClickNoWait()
解决了问题。
答案 0 :(得分:1)
让我为您写一个更完整的例子:
public partial class Form1 : Form
{
//
// Your class properites/variables
//
AlertDialogHandler dialogHandler;
[DllImport("User32.dll")]
public static extern Int32 FindWindow(String lpClassName, String lpWindowName);
//
// Some methods/functions declarations
//
public void SomeInitMethod()
{
dialogHandler = new AlertDialogHandler()
browse.AddDialogHandler(dialogHandler);
}
public void SampleMethod()
{
IntPtr hwndTmp = (IntPtr)FindWindow("#32770", "Dialog Title");
WatiN.Core.Native.Windows.Window popUpDialog = new Window(hwndTmp);
dialogHandler.HandleDialog(popUpDialog);
//
// The line above will find the OK button for you and click on it,
// from here you continue with the rest of your code.
}
}
希望这有点但更清楚。
答案 1 :(得分:0)
因为它是一个Win32对话框,你可以获得窗口弹出窗口的句柄(你知道样式,你知道窗口的标题,如果你不知道你可以用WinSpy ++找到的样式,只需打开工具并将靶心指向警报,它将为您提供该窗口的所有详细信息)
// #32770 is the window style, just to make the search more confined.
IntPtr hwndTmp = (IntPtr)FindWindow("#32770", "This should be the title of the alert");
Window alertDialog = new Window(hwndTmp);
从这里起,您将能够将WatiN视为常规对话框(您应该使用HandleDialog将alertDialog作为参数传递,等等,如果不清楚,请告诉我,我会增强响应)。< / p>
答案 2 :(得分:0)
我将@ ProgrammerV5的答案标记为真正的答案,因为它引导我使用此代码。我只发布这个答案,因为它直接与SpecFlow和WatiN有关。
我有三个不同的SpecFlow步骤,点击了一个按钮,它产生了alert
,断言警报框中有我期望的文本,最后一步点击“确定”。
示例SpecFlow场景
Scenario: Doing something really important
When I click the "Save and Continue" button
Then I should see the validation error alert
When I click OK in the validation error alert
Then I continue on with the rest of this Scenario...
首先,我创建了一个快速帮助方法来查找alert
对话框:
<强> TestProject /助手/ StepHelper.cs 强>
public static class StepHelper
{
[DllImport("User32.dll")]
public static extern Int32 FindWindow(String lpClassName, String lpWindowName);
public static WatiN.Core.Native.Windows.Window GetAlertBox()
{
IntPtr hwndTmp = (IntPtr)FindWindow("#32770", "Message from webpage");
return new WatiN.Core.Native.Windows.Window(hwndTmp);
}
}
这使您可以在Internet Explorer 8中获取alert
框的支持
When I click the "Save and Continue" button
的步骤定义:
[When(@"I click the ""(.*)"" button")]
public void WhenIClickTheButton(string buttonText)
{
Button button = browser.Button(Find.ByValue(buttonText).Or(Find.ByText(buttonText)));
Assert.IsTrue(button.Exists, "No button with text '{0}' was found", buttonText);
button.ClickNoWait();
}
对button.Click()
或button.ClickNoWait()
的调用是产生警报框的内容。只是调用Click()
方法会导致WatiN等待该事件在从方法调用返回之前完全处理。由于警报框已打开并阻止页面,因此单击事件未完成,从而导致对Click()
的调用完全停止。我通过调用ClickNoWait()
来解决这个问题,这是一种点击页面上元素的“火与忘记”方式。现在弹出警报框,但测试运行器可以前进到下一个SpecFlow步骤。
Then I should see the validation error alert
的步骤定义:
[Then(@"I should see the validation error alert")]
public void ThenIShouldSeeTheValidationErrorAlert()
{
var alert = StepHelper.GetAlertBox();
Assert.IsTrue(alert.Message.Contains("An error has occurred"),
"An alert was found, but contained the wrong message ('{0}')", alert.Message);
}
这里我使用我之前创建的StepHelper.GetAlertBox()
方法来获取代表警报框的WatiN.Core.Native.Windows.Window
对象的句柄。然后它是一个简单的Assert.IsTrue
,确保警报中显示的消息实际上是我们的“验证失败”消息(我们在此页面上还有其他警报)。
最后,我们需要关闭提醒框。
When I click OK in the validation error alert
的步骤定义:
[When(@"I click OK in the validation error alert")]
public void WhenIClickOKInTheValidationErrorAlert()
{
var alert = StepHelper.GetAlertBox();
Assert.IsTrue(alert.Message.Contains("An error has occurred"),
"An alert was found, but contained the wrong message ('{0}')", alert.Message);
alert.ForceClose();
}
这里我们只是从帮助程序中获取警报框对象,并调用ForceClose
来关闭警告框,因为单击“确定”或右上角的“X”按钮基本上会执行相同的操作。 / p>