Selenium 4 : How to capture screenshot - hook

I need an After method to capture a screenshot compatible with Selenium 4 Java

#After
public void tearDown(Scenario scenario) {
if (scenario.isFailed()) {
final byte[] screenshot = ((TakesScreenshot) Driver.get()).getScreenshotAs(OutputType.BYTES);
scenario.attach(screenshot, "image/png", "screenshot");
}
Driver.closeDriver();
}

Related

How to attach screenshot to steps using AbstractTestNGCucumberTests?

I want to attach screenshot to steps that is generated cucumber html report. My project use AbstractTestNGCucumberTests.
This is my takeScreenshot method:
public static void takeScreenshot(io.cucumber.core.api.Scenario scenario,
WebDriver driver, File screenShotFile) {
final byte[] screenshot = ((TakesScreenshot) driver).getScreenshotAs(OutputType.BYTES);
scenario.embed(screenshot, "image/png");
try {
OutputStream os = new FileOutputStream(screenShotFile);
os.write(screenshot);
Log.debug("Successfully save screenshot");
os.close();
} catch (Exception ex) {
Log.error("Exception : " + ex);
}
}
I try to get Scenario by declaring anotation io.cucumber.java.Before
But Scenario is null
Please help me how to get io.cucumber.core.api.Scenario or another way to attach screenshot in steps for reporting
I fixed my problem. Cucumber hook #Before is just run in location that is defined in #CucumberOptions(glue=my-path). My Class TestSuiteMaster is in another path, so Scenario is null.
I created a class CucumberHook in directory stepDefinition and take screen shot method in hook #After, everything work great.
This is my CucumberHook class:
public class CucumberHook extends WebTestSuiteMaster {
#After
public void take_screenshot_after_finished_scenario(Scenario scenario) {
String imageFileName = "Screen shot-" + scenario.getName() + "-"
+ new SimpleDateFormat("MM-dd-yyyy_HH-mm").format(new Date()) + ".png";
File imageFile = new File(System.getProperty("user.dir") + "//screenshots//" + imageFileName);
SeleniumWebHelper.takeScreenshot(scenario, driver, imageFile);
}
}

Accessing test context data in custom cucumber formatter/listener

I am creating some kind of custom reporting with cucumber with custom listener/formatter. but I am unable to add some data from test context to my report.
I know we share data/state between steps using cucumber-picocontainer, but my question is how can I access test context data from the custom listener/formatter that i am writing?
Cucumber-Java : 5.2.0
Update: Adding more details. is there a way i can use use context object in the custom listener/plugin. i would like to context.setFailMessage(""); from the custom listener.
Thanks,
Vikas
In order to create custom reporting in cucumber, you have to follow the below steps.
Step 1: Implement ConcurrentEventListener interface
public class DesktopStepDisplayer implements ConcurrentEventListener
Step 2: Add the implementation in EventHandler as show below
private EventHandler<TestStepStarted> eventHandler = new EventHandler<TestStepStarted>()
{
public void receive(TestStepStarted event)
{
if(event.getTestStep() instanceof PickleStepTestStep)
{
String message = ((PickleStepTestStep)event.getTestStep()).getStep().getText();
}
};
public void setEventPublisher(EventPublisher publisher) {
publisher.registerHandlerFor(TestStepStarted.class, eventHandler);
}
Step 3: Set the event publisher
public void setEventPublisher(EventPublisher publisher) {
publisher.registerHandlerFor(TestStepStarted.class, eventHandler);
}
Entire Script:
public class DesktopStepDisplayer implements ConcurrentEventListener {
private EventHandler<TestStepStarted> eventHandler = new EventHandler<TestStepStarted>()
{
public void receive(TestStepStarted event)
{
if(event.getTestStep() instanceof PickleStepTestStep)
{
String message = ((PickleStepTestStep)event.getTestStep()).getStep().getText();
}
};
public void setEventPublisher(EventPublisher publisher) {
publisher.registerHandlerFor(TestStepStarted.class, eventHandler);
}
}

Is there a way to close and reopen browser when using cucumber scenario outlines and webdriver io

I'm using v5 of web driver io and a cucumber framework. I have scenario outlines with multiple examples. I would like to close the browser and reopen it in between the examples so I have a clean webpage. But I can't find a way to do this. I'm sure I've seen anything about this but I can't find it.
I've looked through the webdriverio docs and the last things I can find was from 2016 which said it wasn't possible but there was a discussion about implementing something but I can't find any more detail.
Are you looking for this:
browser.reloadSession()
https://webdriver.io/docs/api/browser/reloadSession.html
You can use hooks, I share an example below.
UiHooks.java :
import cucumber.api.Scenario;
import cucumber.api.java.After;
import cucumber.api.java.Before;
public class UiHooks {
public static final String BASE_URL = "https://baseURL/";
private Scenario scenario;
#Before
public void beforeScenario(Scenario scenario) {
this.scenario = scenario;
}
#After(order = 1) //This will run first
public void afterScenario() {
if (scenario.isFailed()){
//do something like Secreen Shot or logger
}
}
#After(order = 0)//This will run second
public void afterTest() {
if (HookUtil.driver != null) {
HookUtil.driver.close();
}
if (HookUtil.seleniumBase != null) {
HookUtil.seleniumBase.stopService();
}
}
}
HookUtil.java :
public class HookUtil {
public static WebDriver driver = null;
public static SeleniumBase seleniumBase = null;
}
And then you can create a setup and call in the first step :
private void Setup() {
seleniumBase = new SeleniumBase(UiHooks.BASE_URL);
driver = seleniumBase.getDriver();
HookUtil.driver = driver;
HookUtil.seleniumBase = seleniumBase;
}

Cucumber, biggest challenge, browser invoke

In my framework each feature file when converted to step def I have to put browser invoke codes (SetProperties) and for each operations new windows comes. Please help me resolve the issue I tried inherentance where i put the codes and extended to step def classes did not work. I want to open one browser and that will do the operations for every feature files.
For example: I have a feature file for login content verification and another feature file for after login.
I put in the login the userName and Password again I had to put userName and password cor the other feature file after login along with browser invoke codes.
if you are still looking for answer. I would suggest initialize your browser in every step definition file or inside page object class(if you are using POM). create a class e.g: TestContext.java initialize your webdriver in that class.
public class TestContext {
private WebDriverLibrary webDriverLibrary;
private PageObjectLibrary pageObjectLibrary;
public TestContext() {
webDriverLibrary = new WebDriverLibrary();
pageObjectLibrary = new PageObjectLibrary(webDriverLibrary.getDriver());
}
// return WebDriverLibrary object
public WebDriverLibrary getWebDriverLibrary() {
return webDriverLibrary;
}
// return PageObjectLibrary object
public PageObjectLibrary getPageObjectLibrary() {
return pageObjectLibrary;
}
}
public class WebDriverLibrary {
private static WebDriver driver;
private static DriverType driverType;
private static EnvironmentType environmentType;
public WebDriverLibrary() {
driverType = FileReaderLibrary.getInstance().getConfigReader().getBrowser();
environmentType = FileReaderLibrary.getInstance().getConfigReader().getEnvironment();
}
// return webdriver instance
public WebDriver getDriver() {
if (driver == null)
driver = createDriver();
return driver;
}
private WebDriver createDriver() {
switch (environmentType) {
case LOCAL:
driver = createLocalDriver();
break;
case REMOTE:
driver = createRemoteDriver();
break;
}
return driver;
}
}
Hope this helps you.

LWUIT TextArea NullPointerException

I run LWUITDemo, Some UI can not be shown successful.All of them are TextArea contained by Form.If I change TextArea to Label, it work well.
Sorry, I run it in nokia s40 sdk 2.0. When I run most of codes that include TextArea, exception ocurred;
The Code Like That(From LWUITDemo):
Form aboutForm = new Form("About");
aboutForm.setScrollable(true);
aboutForm.setLayout(new BorderLayout());
TextArea aboutText = new TextArea(getAboutText(), 5, 10);
aboutText.setEditable(false);
aboutForm.addComponent(BorderLayout.CENTER, aboutText);
aboutForm.show();
When I run it, it faild:
Form: showModal
java.lang.NullPointerException
at com.sun.lwuit.TextArea.shouldShowHint(+21)
at com.sun.lwuit.TextArea.calcPreferredSize(+4)
at com.sun.lwuit.Component.preferredSize(+63)
...
You Could Check below Code:
import com.sun.lwuit.Display;
import com.sun.lwuit.Form;
import com.sun.lwuit.TextArea;
import com.sun.lwuit.layouts.BorderLayout;
import javax.microedition.midlet.*;
public class TextMidlet extends MIDlet {
private Form aboutForm;
public TextMidlet() {
Display.init(this);
aboutForm = new Form();
aboutForm.setScrollable(true);
aboutForm.setLayout(new BorderLayout());
}
public void startApp() {
TextArea aboutText = new TextArea("hiiiiiiiiiiiiii", 5, 10);
aboutText.setEditable(false);
aboutForm.addComponent(BorderLayout.CENTER, aboutText);
aboutForm.show();
}
public void pauseApp() {
}
public void destroyApp(boolean unconditional) {
}
}
The code looks good to me. Please check that getAboutText() returns a String and does not return null.
If this does not help, you can use the LWUIT-Sources to debug your code. Set a breakpoint at TextArea.shouldShowHint and find out what it is that is null.
Check
import com.sun.lwuit.TextArea;

Resources