Не удается поделиться экземпляром веб-драйвера между разными историями, которые имеют общие шаги жизненного цикла в JBehave - PullRequest
0 голосов
/ 23 мая 2018

У меня есть два разных класса шагов, которые имеют общий жизненный цикл до и после шагов.Поэтому я создал общий класс шагов, в котором код инициализации и очистки веб-драйвера используется в качестве жизненного цикла до и после методов.Этот общий класс расширяется обоими классами определения шага.При запуске этих историй я вижу исключение нулевого указателя при доступе к веб-драйверу в классе второго шага.Дальнейшая отладка Я заметил, что общие шаги вызываются с использованием объекта класса первого шага для каждого сценария в файле истории.

My Story File 1.

Meta:
@author prasanta biswas
@theme UI Test

Narrative:
As a Facebook User
In order to update my status
I want to login to my Facebook account
So that I can update my status message

Lifecycle:
Before:
Scope: SCENARIO
Given I initialize my chrome browser instance
After:
Scope: SCENARIO|STORY
Outcome: ANY
Given I cleanup my browser instance

Scenario: Update Facebook status message
Meta:
@type positive
@data valid
@app facebook

Given I have a Facebook account
And I open Facebook in my web browser with the <url>
And I login to Facebook with <username> and <password>
Then I check if status message box is present in the homepage after successful login
When I put my status <message> in the status box
And I click post button
Then I should see my new status <message> in my news feeds

Examples:
|username|password|url|message|
|VALID_USERNAME|VALID_PASSWORD|https://www.facebook.com|Hi Facebook|

My Story File2.

Meta:
@author prasanta biswas
@theme UI Test

Narrative:
As a wallethub user
I want to review a particual insurance policy
So that the review appears in my review list


Lifecycle:
Before:
Scope: SCENARIO
Given I initialize my chrome browser instance
After:
Scope: SCENARIO|STORY
Outcome: ANY
Given I cleanup my browser instance


Scenario: Create review for a particual walletHub insurance policy
Meta:
@type positive
@data valid
@app wallethub

Given I have a WalletHub test account
And I open wallethub in the web browser using <url>
And I login to my wallethub account with <email> and <password>
Then I should see my <username> on my homepage
Given I navigate to <reviewUrl> after login
And I count the current review count in my review list
And I navigate to <insuranceCompanyUrl>
When I click Write a Review button
Then I should see new review page
Given I select insurance <policy> from insurance list in new review page
And I apply rating <star>
And I put my review <text>
When I click submit button
Then I should see confirmation <message>
And I should see a my new review <text> in my <reviewUrl>

Examples:
|email|password|url|username|reviewUrl|insuranceCompanyUrl|policy|text|star|message|
|eaxmple@gmail.com|asssdd|https://wallethub.com/|pthewizard|https://wallethub.com/profile/pthewizard/reviews/|http://wallethub.com/profile/test_insurance_company/|Health|This is my first reviewHealthPolicy.|5|Awesome!|

Класс CommonStep:

    package io.jbehavetutorials.steps.common;

    import io.jbehavetutorials.testutility.BrowserFactory;
    import org.jbehave.core.annotations.Given;
    import org.jbehave.core.annotations.Named;
    import org.openqa.selenium.WebDriver;

    /**
     * Created by prasantabiswas on 23/05/18.
     */
    public class CommonSteps {

        protected WebDriver webDriver;

        @Given("I initialize my $browserName browser instance")
        public void setUpMethod(@Named("browserName") String browser)
        {
            webDriver = BrowserFactory.getDriver(browser);
        }

        @Given("I cleanup my browser instance")
        public void tearDownMethod()
        {
            // Cleanup
            if(webDriver != null)
                webDriver.quit();
        }
    }

Мой класс определения первого шага:

package io.jbehavetutorials.steps.facebook;

import io.jbehavetutorials.appmodule.facebook.FacebookApp;
import io.jbehavetutorials.constants.Browser;
import io.jbehavetutorials.steps.common.CommonSteps;
import io.jbehavetutorials.testutility.BrowserFactory;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.jbehave.core.annotations.*;
import org.junit.Assert;
import org.openqa.selenium.WebDriver;

import java.net.MalformedURLException;

/**
 * Created by prasantabiswas on 21/05/18.
 */
public class FacebookStatusPost extends CommonSteps{
    FacebookApp facebookApp;
    Logger logger = LogManager.getLogger(FacebookStatusPost.class);

    @Given("I have a Facebook account")
    @Pending
    public void iHaveAFacebookAccount()
    {
        try {
            facebookApp = new FacebookApp(webDriver); // Working perfectly here
            Assert.assertTrue("Facebook object creation failed",facebookApp!=null);
        }
        catch (Exception e)
        {
            logger.error("Error",e);
        }
    }
}

Мой класс определения второго шага:

package io.jbehavetutorials.steps.wallethub;

import io.jbehavetutorials.appmodule.wallethub.WalletHubApp;
import io.jbehavetutorials.constants.Browser;
import io.jbehavetutorials.steps.common.CommonSteps;
import io.jbehavetutorials.testutility.BrowserFactory;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.jbehave.core.annotations.*;
import org.junit.Assert;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;

import java.net.MalformedURLException;

/**
 * Created by prasantabiswas on 21/05/18.
 */
public class WalletHubReviewInsurance extends CommonSteps {
    WalletHubApp wallethubApp;
    int reviewCount = 0;
    Logger logger = LogManager.getLogger(WalletHubReviewInsurance.class);

    @Given("I have a WalletHub test account")
    public void iHaveAWallerHubTestAccount()
    {
        try{
            wallethubApp = new WalletHubApp(webDriver);//Getting null pointer here
        }
        catch (Exception e)
        {
            logger.error("Error",e);
        }
    }
}

Класс карты истории:

package io.jbehavetutorials;

import io.jbehavetutorials.steps.facebook.FacebookStatusPost;
import io.jbehavetutorials.steps.wallethub.WalletHubReviewInsurance;
import io.jbehavetutorials.steps.weatherapi.WeatherAPITest;
import org.jbehave.core.embedder.StoryControls;
import org.jbehave.core.junit.JUnitStories;

import java.text.SimpleDateFormat;
import java.util.List;

import org.jbehave.core.Embeddable;
import org.jbehave.core.configuration.Configuration;
import org.jbehave.core.configuration.MostUsefulConfiguration;
import org.jbehave.core.i18n.LocalizedKeywords;
import org.jbehave.core.io.CodeLocations;
import org.jbehave.core.io.LoadFromClasspath;
import org.jbehave.core.io.StoryFinder;
import org.jbehave.core.model.ExamplesTableFactory;
import org.jbehave.core.model.TableTransformers;
import org.jbehave.core.parsers.RegexStoryParser;
import org.jbehave.core.reporters.StoryReporterBuilder;
import org.jbehave.core.reporters.SurefireReporter;
import org.jbehave.core.steps.*;
import org.jbehave.core.steps.ParameterConverters.DateConverter;
import org.jbehave.core.steps.ParameterConverters.ExamplesTableConverter;

import static org.jbehave.core.io.CodeLocations.codeLocationFromClass;
import static org.jbehave.core.reporters.Format.CONSOLE;
import static org.jbehave.core.reporters.Format.HTML;
import static org.jbehave.core.reporters.Format.TXT;
import static org.jbehave.core.reporters.Format.XML;

/**
 * <p>
 * {@link Embeddable} class to run multiple textual stories via JUnit.
 * </p>
 * <p>
 * Stories are specified in classpath and correspondingly the {@link LoadFromClasspath} story loader is configured.
 * </p> 
 */
public class StoryMap extends JUnitStories {

    public StoryMap() {
        configuredEmbedder().embedderControls().doGenerateViewAfterStories(true).doIgnoreFailureInStories(true)
                .doIgnoreFailureInView(true).useThreads(1);
//        configuredEmbedder().useMetaFilters(Arrays.asList("+type negative"));
    }

    @Override
    public Configuration configuration() {
        Class<? extends Embeddable> embeddableClass = this.getClass();
        // Start from default ParameterConverters instance
        ParameterConverters parameterConverters = new ParameterConverters();
        // Start from default ParameterControls instance
        ParameterControls parameterControls = new ParameterControls();
        // factory to allow parameter conversion and loading from external resources (used by StoryParser too)
        ExamplesTableFactory examplesTableFactory = new ExamplesTableFactory(new LocalizedKeywords(), new LoadFromClasspath(embeddableClass),parameterConverters,parameterControls, new TableTransformers());
        // add custom converters
        parameterConverters.addConverters(new DateConverter(new SimpleDateFormat("yyyy-MM-dd")),
                new ExamplesTableConverter(examplesTableFactory));
        return new MostUsefulConfiguration()
                //.usePendingStepStrategy(new FailingUponPendingStep())
                .useStoryControls(new StoryControls().doDryRun(false))
                .useStoryLoader(new LoadFromClasspath(embeddableClass))
                .useStoryParser(new RegexStoryParser(examplesTableFactory))
//                .useStoryParser(new GherkinStoryParser())
                .useStoryReporterBuilder(new StoryReporterBuilder()
                .withSurefireReporter(new SurefireReporter(embeddableClass))
                    .withCodeLocation(CodeLocations.codeLocationFromClass(embeddableClass))
                    .withDefaultFormats()
                    .withFormats(CONSOLE, TXT, HTML, XML)
                    .withFailureTrace(true)
                    .withFailureTraceCompression(true))
            .useParameterConverters(parameterConverters)
            .useParameterControls(parameterControls);
    }

    @Override
    public InjectableStepsFactory stepsFactory() {
        return new InstanceStepsFactory(configuration(), new FacebookStatusPost(), new WalletHubReviewInsurance(), new WeatherAPITest());
//        return new ScanningStepsFactory(configuration(),"io.jbehavetutorials.steps"); //requires reflection dependency
    }

    @Override
    protected List<String> storyPaths() {
        return new StoryFinder().findPaths(codeLocationFromClass(this.getClass()), "**/*.story", "**/excluded*.story");

    }

}

Есть ли способ вызвать эти общие методы жизненного цикла отдельно от разных объектов класса определения шага, чтобы отдельный экземпляр веб-драйвера создавался для разных классов определения шага.

1 Ответ

0 голосов
/ 24 мая 2018

Обходной путь - сделать экземпляр драйвера static в классе CommonSteps.Это не конкретное решение, так как его нельзя использовать с несколькими потоками, запускающими истории одновременно, так как это сделает экземпляр драйвера уязвимым.

...