There is a rule to take a screenshot if the test falls:

@Rule public ScreenShotOnFailRule screenShotOnFailRule = new ScreenShotOnFailRule(); 

Also after each After test:

  @After public void afterTest() { WebDriverFactory.finishBrowser(); } /** * Finishes browser */ public static void finishBrowser() { if (driver != null) { driver.quit(); driver = null; } } 

When executing, it gives a NullPointerExeption error that the driver was not found to take the screenshot.

  • As far as I understand by the static method, you really need @AfterClass - it will probably solve this race condition in parallel - etki
  • BeforeClass and AfterClass do not suit me, because the browser does not log in after each test. T, e remains open and will continue to work. And I need to initialize it with each test - Alexander Dermenzhi

1 answer 1

From the documentation for @Rule :

TestRule ’ll be TestRule to TestRule .

Those. @Rule can only wrap the sequence @Before -> @Test -> @After , it cannot wedge between @Test and @After , and you just need this (take a screenshot before @After works).

To solve this problem, you need to raise / lower the browser not in @Before / @After , but in another @Rule (inherited from an ExternalResource , for example). And in order for these things to be performed in the correct order, you will have to use RuleChain , since in general, junit does not guarantee the execution order of @Rule -fields:

 public class SomeTests { @Rule public RuleChain ruleChain = RuleChain .outerRule(new WebDriverRule()) .around(new ScreenShotOnFailRule()); @Test public void test() { // ... } } 

WebDriverRule can be implemented like this:

 import org.junit.rules.ExternalResource; public class WebDriverRule extends ExternalResource { @Override protected void after() { WebDriverFactory.finishBrowser(); } } 

If inside WebDriverRule need access to some fields of the test class, you can add a constructor and pass the values ​​there. Or make the class nested.