javaplaywrighthttpsessionplaywright-java

How to share HttpSession between pages with Playwright Java


I am writing a test with Playwright, for a java application setting attributes in the user httpsession, to be shared across different pages.

The test opens the app in one page, adds an attribute to the httpsession. Then it opens a new page, adds a different attribute and expects to find both attributes in the session.

But Playwright's documentation mentions that each page is isolated by default, and by design.

Is there a way to bypass this isolation? Or a workaround that would work with Playwright?

My code:

The application deployed and tested is linked above (ClusterHAJSP from glassfish-samples). The test itself:

It basically deploys the application in 2 servers, opens page1, adds attribute1, opens page2, adds attribute2 and expect to find the attribute added in page1 (a future step would be to reload page1 and find attribute2)

public class DualSessionsIT {

    private static BrowserContext context;

    public static WebArchive createClusterJsp() {
        WebArchive archive = ShrinkWrap.getWebArchive()
                .addAsWebInfResource(new File("src/test/resources/clusterjsp/clusterjsp-war/web/WEB-INF/web.xml"))
                .addAsWebResource(new File("src/test/resources/clusterjsp/clusterjsp-war/web/HaJsp.jsp"))
                .addAsWebResource(new File("src/test/resources/clusterjsp/clusterjsp-war/web/ClearSession.jsp"))
                .addAsManifestResource("");
        return archive;
    }


    @Deployment(name = "instance1", order = 1)
    public static WebArchive instance1() {
        return createClusterJsp();
    }

    @Deployment(name = "instance2", order = 2)
    public static WebArchive instance2() {
        return createClusterJsp();
    }

    @ArquillianResource
    @OperateOnDeployment("instance1")
    private URL deployment1URL;

    @ArquillianResource
    @OperateOnDeployment("instance2")
    private URL deployment2URL;

    //Load the desired page
    static public Page openPage(String url) {
        if (context == null) {
            Playwright playwright = Playwright.create();
            Browser browser = playwright.chromium().launch(new BrowserType.LaunchOptions().setHeadless(false));
            context = browser.newContext();
        }
        Page page = context.newPage();
        page.navigate(url);
        page.waitForLoadState();
        assertThat(page).hasTitle("Cluster - Ha JSP Sample ");
        return page;
    }

    @Test
    public void addAndReadAttributes() throws MalformedURLException, InterruptedException {
        Page page1 = openPage(deployment1URL.toString());
        ClusterHAJSPPage.enterNameAttribute(page1, "attribute1");
        ClusterHAJSPPage.enterValueAttribute(page1, "value1");
        ClusterHAJSPPage.addSessionData(page1);
        String results = ClusterHAJSPPage.readDataHttpSession(page1);
        assertThat(results, containsString("attribute1 = value1"));

        Page page2 = openPage(deployment2URL.toString());
        page2.bringToFront();
        ClusterHAJSPPage.enterNameAttribute(page2, "attribute2");
        ClusterHAJSPPage.enterValueAttribute(page2, "value2");
        ClusterHAJSPPage.addSessionData(page2);
        String results2 = ClusterHAJSPPage.readDataHttpSession(page2);
        assertThat(results2, containsString("attribute1 = value1"));
    }
}

Solution

  • Not a direct answer to my initial question, but I got my test working by using the same page, navigating to the second url, checking the http session and adding an attribute, then back to the first page and checking the session again.

    My test becomes:

    @RunWith(ArquillianTestRunner.class)
    public class DualSessionsIT {
        public static WebArchive createClusterJsp() {
        WebArchive archive = ShrinkWrap.create(WebArchive.class, "clusterjsp.war")
                .addAsWebInfResource(new File("src/test/resources/clusterjsp/clusterjsp-war/web/WEB-INF/sun-web.xml"))
                .addAsWebInfResource(new File("src/test/resources/clusterjsp/clusterjsp-war/web/WEB-INF/web.xml"))
                .addAsWebResource(new File("src/test/resources/clusterjsp/clusterjsp-war/web/HaJsp.jsp"))
                .addAsWebResource(new File("src/test/resources/clusterjsp/clusterjsp-war/web/ClearSession.jsp"))
                .addAsManifestResource(new File("src/test/resources/clusterjsp/clusterjsp-war/web/MANIFEST.MF"));
        return archive;
        }
    
    // Deployment with testable = false as otherwise, Arquillian would add its own libraries to the war
    // including the library arquillian-jakarta-servlet-protocol.jar, preventing clusterjsp to work as intended
    @Deployment(name = "Instance1", order = 1, testable = false)
    @TargetsContainer("instance1")
    public static WebArchive microInstance1() {
        return createClusterJsp();
    }
    
    @ArquillianResource
    @OperateOnDeployment("microInstance1")
    private URL deployment1URL;
    
    @Deployment(name = "Instance2", order = 2, testable = false)
    @TargetsContainer("instance2")
    public static WebArchive microInstance2() {
        return createClusterJsp();
    }
    
    @ArquillianResource
    @OperateOnDeployment("Instance2")
    private URL deployment2URL;
    
    
    @Test
    @RunAsClient
    public void addAndReadAttributes() throws MalformedURLException, InterruptedException {
        try (Page page = ClusterHAJSPPage.openNewPage(deployment1URL.toString())) {
            ClusterHAJSPPage.enterNameAttribute(page, "attribute1");
            ClusterHAJSPPage.enterValueAttribute(page, "value1");
            ClusterHAJSPPage.addSessionData(page);
            String results = ClusterHAJSPPage.readDataHttpSession(page);
            assertThat(results, containsString("attribute1 = value1"));
    
            ClusterHAJSPPage.openNewUrl(page, deployment2URL.toString());
            ClusterHAJSPPage.enterNameAttribute(page, "attribute2");
            ClusterHAJSPPage.enterValueAttribute(page, "value2");
            ClusterHAJSPPage.addSessionData(page);
            String results2 = ClusterHAJSPPage.readDataHttpSession(page);
            assertThat(results2, containsString("attribute1 = value1"));
    
            ClusterHAJSPPage.openNewUrl(page, deployment1URL.toString());
            ClusterHAJSPPage.reloadPage(page);
            String results3 = ClusterHAJSPPage.readDataHttpSession(page);
            assertThat(results3, containsString("attribute1 = value1"));
            assertThat(results3, containsString("attribute2 = value2"));
        }
    }
    

    }