如何在每个Selenium操作后调用Screenshot方法

ijnw1ujt  于 2023-02-04  发布在  其他
关注(0)|答案(1)|浏览(144)

我的工作与规范流(如果有这样一个函数存在)编程语言C#.
我希望在每个selenium操作之后都能截取一个屏幕截图。为什么?-〉我希望在第一次自动化之后,创建一系列成功测试运行的图片(这样将来的业务分析师就可以通过图片快速地看到,用哪个测试用例ID测试了什么)。应该可以通过一个标志来指定是否应该创建屏幕截图。所以我的主要问题是:如何确保在每次“driver.FindElement....“和“www.example.com“或类似操作后自动调用屏幕截图函数variable.click?我不想手动插入“makeScreenshot()”。如果每次方法调用后都能调用不同的方法,那就太好了。这样就可以查找“命令是什么”。如果语法匹配类似“单击()",屏幕截图被触发,否则不会。如果没有这样的东西。类似于“屏幕截图(variable.Click())”的东西也是可以想象的。那仍然是干净的,很容易通过复制粘贴在任何地方实现。
有人有想法或链接吗?(我是一个有点菜鸟,需要代码示例开始)

6rqinv9w

6rqinv9w1#

**可能的解决方案1:**您可以为IWebElement添加一个extension method到您的项目中,这将允许您创建自己的自定义单击并查找方法,在单击后进行屏幕截图。

public static class IWebElementExtensions
    {
        public static void ClickAndScreenshot(this IWebElement element,
           IWebDriver driver,
           ScenarioContext scenarioContext)
        {
            element.Click();

            Screenshot ss = ((ITakesScreenshot)driver).GetScreenshot();
            ss.SaveAsFile($"{scenarioContext.ScenarioInfo.Title}_{scenarioContext.StepContext.StepInfo.Text.Replace("\"", "")}.png",
            ScreenshotImageFormat.Png);
        }
    }

如果您将上述类添加到项目中并在步骤中引用它,它将单击元素,然后获取屏幕截图并将场景和步骤信息添加到文件名中,以便稍后识别它(考虑您计划如何管理这些屏幕截图,可能值得为每个场景添加一个子文件夹,或将日期时间添加到文件名中以进行诊断)。
然后可以在Specflow步骤中使用此方法:

[When(@"I click a login button")]
        public void WhenIClickALoginButton()
        {
            By someLoginButton = By.Id("login");

            _driver.FindElement(someLoginButton).ClickAndScreenshot(_driver, _scenarioContext);
        }

你可以做一些类似的事情来查找元素,你可以创建一个扩展方法来查找元素,获取一个屏幕截图,然后将元素作为一个返回类型返回给你的WebDriver。
您必须更改当前单击()利用此新方法的方法(查找和替换应该有助于使这一点微不足道),但如果你需要改变它,你的屏幕截图代码将全部放在一个地方。这样做意味着你可以挑选和选择何时调用该方法,以及根据你的步骤,因为如果您对某个特定步骤中的屏幕截图不感兴趣,可以坚持使用原始的Click()方法。

潜在解决方案2:

我觉得在每一个Specflow步骤之后都要做一个截图,而不是每一个Selenium操作,这是一个值得一提的潜在解决方案,关注用户操作块,而不是每一个Selenium操作。
例如,您可以配置一个hooks文件,以便在每个specflow步骤之后进行屏幕截图:

[Binding]
    public class Hooks
    {
        IWebDriver _driver;

        public Hooks(IWebDriver driver)
        {
            _driver = driver;
        }

        [Scope(Tag = "screenshot")]
        [AfterStep]
        public void TakeScreenshotAfterStep(ScenarioContext scenarioContext)
        {
            Screenshot screenshot = ((ITakesScreenshot)_driver).GetScreenshot();
            screenshot.SaveAsFile($"{scenarioContext.ScenarioInfo.Title}_{scenarioContext.StepContext.StepInfo.Text}.png",
            ScreenshotImageFormat.Png);
        }

        [AfterScenario]
        public void AfterScenario()
        {
            _driver.Dispose();
        }
    }

对于示例功能:

Feature: Login

@screenshot
Scenario: Successful Login
GIVEN I navigate to stack overflow
WHEN I login
THEN I am logged in

@someOtherTag
Scenario: API test with no UI
GIVEN I have a cool API
WHEN I do a GET
THEN I GET some cool stuff

这将在成功登录场景的每一步后生成3个屏幕截图,但由于after步骤上的标记范围,它不会为API测试生成任何屏幕截图,该步骤应该勾选能够指定何时执行此操作的框。
以上依赖于你的Specflow步骤不要太大...如果你在一个步骤中做多个大块的用户操作,它可能会跳过很多,但如果这只是一个罕见的情况,你可以做一些额外的屏幕截图在这些步骤中使用从潜在的解决方案1的扩展。
我希望这能有所帮助,我知道这不是一个纯粹的答案,但从经验来看,当这些类型的截图可以是有用的,我会推荐解决方案2,并利用它作为一个机会,以确保您的规范流步骤没有做太多。

相关问题