From 2c298be1cfb17bfc90c0dcd7b1714a345c8d33f6 Mon Sep 17 00:00:00 2001 From: Yauheni Hapanovich Date: Fri, 14 Jun 2024 13:34:00 +0300 Subject: [PATCH] Implement Cookie Steps code logic for Playwright --- .../pages/plugin-web-app-playwright.adoc | 2 + .../plugins/partials/web-cookie-steps.adoc | 131 +++++++++++++ .../web/playwright/helper/CookieHelper.java | 87 +++++++++ .../ui/web/playwright/steps/CookieSteps.java | 176 ++++++++++++++++++ .../main/resources/vividus-plugin/spring.xml | 4 + .../playwright/steps/CookieStepsTests.java | 130 +++++++++++++ .../integration/CookieStepsPlaywright.story | 16 ++ 7 files changed, 546 insertions(+) create mode 100644 docs/modules/plugins/partials/web-cookie-steps.adoc create mode 100644 vividus-plugin-web-app-playwright/src/main/java/org/vividus/ui/web/playwright/helper/CookieHelper.java create mode 100644 vividus-plugin-web-app-playwright/src/main/java/org/vividus/ui/web/playwright/steps/CookieSteps.java create mode 100644 vividus-plugin-web-app-playwright/src/test/java/org/vividus/ui/web/playwright/steps/CookieStepsTests.java create mode 100644 vividus-tests/src/main/resources/story/integration/CookieStepsPlaywright.story diff --git a/docs/modules/plugins/pages/plugin-web-app-playwright.adoc b/docs/modules/plugins/pages/plugin-web-app-playwright.adoc index e3d30734b9..a837b668f2 100644 --- a/docs/modules/plugins/pages/plugin-web-app-playwright.adoc +++ b/docs/modules/plugins/pages/plugin-web-app-playwright.adoc @@ -306,3 +306,5 @@ Given I am on page with URL `https://vividus-test-site-a92k.onrender.com/` When I execute javascript `JSON.stringify(window.performance.timing)` and save result to scenario variable `timings` Then number of JSON elements from `${timings}` by JSON path `$.connectStart` is = 1 ---- + +include::plugins:partial$web-cookie-steps.adoc[] diff --git a/docs/modules/plugins/partials/web-cookie-steps.adoc b/docs/modules/plugins/partials/web-cookie-steps.adoc new file mode 100644 index 0000000000..0b5a87ba3e --- /dev/null +++ b/docs/modules/plugins/partials/web-cookie-steps.adoc @@ -0,0 +1,131 @@ +=== Cookie Steps + +==== Validate cookie presence + +Validates whether the certain cookie is set. + +[source,gherkin] +---- +Then cookie with name `$cookieName` is set +---- +* $cookieName - The name of the cookie to check presence. + +.Check the session cookie is present +[source,gherkin] +---- +Then cookie with name `JSESSIONID` is set +---- + +==== Validate cookie absence + +Validates whether the certain cookie is not set. + +[source,gherkin] +---- +Then cookie with name `$cookieName` is not set +---- +* $cookieName - The name of the cookie to check absence. + +.Check the session cookie is not present +[source,gherkin] +---- +Then cookie with name `JSESSIONID` is not set +---- + +==== Set cookies + +Adds the cookies provided in the input xref:ROOT:glossary.adoc#_examplestable[ExamplesTable]. It's allowed to add the +cookies for the current domain only: make sure the web browser is opened at the +expected domain. + +[source,gherkin] +---- +When I set all cookies for current domain:$parameters +---- +* `$parameters` - The parameters of the cookies to set as xref:ROOT:glossary.adoc#_examplestable[ExamplesTable]: ++ +[cols="1,2", options="header"] +|=== + +|Column Name +|Description + +|`cookieName` +|the name of the cookie to set + +|`cookieValue` +|the value of the cookie to set + +|`path` +|the path of the cookie to set + +|=== + +.Set the cookie for the current domain +[source,gherkin] +---- +When I set all cookies for current domain: +|cookieName |cookieValue |path | +|cookieAgreed |2 |/ | +---- + +==== Get cookie value + +Finds the cookie by the name and saves its value to a variable. + +[source,gherkin] +---- +When I save value of cookie with name `$cookieName` to $scopes variable `$variableName` +---- +* `$cookieName` - The name of the cookie to save the value. +* `$scopes` - xref:commons:variables.adoc#_scopes[The comma-separated set of the variables scopes]. +* `$variableName` - The variable name to save the cookie value. + +.Get the value of the session cookie +[source,gherkin] +---- +When I save value of cookie with name `JSESSIONID` to scenario variable `session-id` +---- + +==== Get cookie + +Finds the cookie by the name and saves all its parameters as JSON to a variable. + +[source,gherkin] +---- +When I save cookie with name `$cookieName` as JSON to $scopes variable `$variableName` +---- +* `$cookieName` - The name of the cookie to save. +* `$scopes` - xref:commons:variables.adoc#_scopes[The comma-separated set of the variables scopes]. +* `$variableName` - The variable name to save the cookie. + +.Get the session cookie +[source,gherkin] +---- +When I save cookie with name `JSESSIONID` as JSON to scenario variable `session-id` +---- + +==== Remove cookie + +Removes the certain cookie from the current domain. + +[source,gherkin] +---- +When I remove cookie with name `$cookieName` from current domain +---- +* `$cookieName` - The name of the cookie to remove. + +.Remove the session cookie +[source,gherkin] +---- +When I remove cookie with name `JSESSIONID` from current domain +---- + +==== Remove all cookies + +Removes all cookies from the current domain. + +[source,gherkin] +---- +When I remove all cookies from current domain +---- diff --git a/vividus-plugin-web-app-playwright/src/main/java/org/vividus/ui/web/playwright/helper/CookieHelper.java b/vividus-plugin-web-app-playwright/src/main/java/org/vividus/ui/web/playwright/helper/CookieHelper.java new file mode 100644 index 0000000000..bc0c495da1 --- /dev/null +++ b/vividus-plugin-web-app-playwright/src/main/java/org/vividus/ui/web/playwright/helper/CookieHelper.java @@ -0,0 +1,87 @@ +/* + * Copyright 2019-2024 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.vividus.ui.web.playwright.helper; + +import java.util.Collections; +import java.util.List; + +import com.microsoft.playwright.BrowserContext; +import com.microsoft.playwright.options.Cookie; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.vividus.ui.web.playwright.BrowserContextProvider; + + +public class CookieHelper +{ + private static final Logger LOGGER = LoggerFactory.getLogger(CookieHelper.class); + + private final BrowserContext browserContext; + + public CookieHelper(BrowserContextProvider browserContextProvider) + { + this.browserContext = browserContextProvider.get(); + } + + public void addCookie(String cookieName, String cookieValue, String path, String url) + { + Cookie cookie = new Cookie(cookieName, cookieValue) + .setPath(path) + .setDomain(url); + LOGGER.debug("Adding cookie: {}", cookie); + addCookies(Collections.singletonList(cookie)); + } + + public void addCookies(List cookies) + { + browserContext.addCookies(cookies); + } + + public void deleteAllCookies() + { + browserContext.clearCookies(); + } + + public void deleteCookie(String cookieName) + { + browserContext.clearCookies(new BrowserContext.ClearCookiesOptions().setName(cookieName)); + } + + public Cookie getCookie(String name) + { + for (Cookie cookie : getCookies()) + { + if (cookie.name.equals(name)) + { + return cookie; + } + } + + return null; + } + + public String getValue(Cookie cookie) + { + return cookie.value; + } + + private List getCookies() + { + return browserContext.cookies(); + } +} diff --git a/vividus-plugin-web-app-playwright/src/main/java/org/vividus/ui/web/playwright/steps/CookieSteps.java b/vividus-plugin-web-app-playwright/src/main/java/org/vividus/ui/web/playwright/steps/CookieSteps.java new file mode 100644 index 0000000000..07acdf32ec --- /dev/null +++ b/vividus-plugin-web-app-playwright/src/main/java/org/vividus/ui/web/playwright/steps/CookieSteps.java @@ -0,0 +1,176 @@ +/* + * Copyright 2019-2024 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.vividus.ui.web.playwright.steps; + +import static org.hamcrest.Matchers.notNullValue; +import static org.hamcrest.Matchers.nullValue; + +import java.util.Set; + +import com.microsoft.playwright.options.Cookie; + +import org.apache.commons.lang3.Validate; +import org.jbehave.core.annotations.Then; +import org.jbehave.core.annotations.When; +import org.jbehave.core.model.ExamplesTable; +import org.vividus.context.VariableContext; +import org.vividus.softassert.ISoftAssert; +import org.vividus.ui.web.configuration.WebApplicationConfiguration; +import org.vividus.ui.web.playwright.helper.CookieHelper; +import org.vividus.util.json.JsonUtils; +import org.vividus.variable.VariableScope; + +public class CookieSteps +{ + private final WebApplicationConfiguration webApplicationConfiguration; + private final VariableContext variableContext; + private final ISoftAssert softAssert; + private final CookieHelper cookieHelper; + private final JsonUtils jsonUtils; + + private final String COOKIE_IS_SET = "Cookie with the name '%s' is set"; + + public CookieSteps(VariableContext variableContext, WebApplicationConfiguration webApplicationConfiguration, + ISoftAssert softAssert, CookieHelper cookieHelper, JsonUtils jsonUtils) + { + this.variableContext = variableContext; + this.webApplicationConfiguration = webApplicationConfiguration; + this.softAssert = softAssert; + this.cookieHelper = cookieHelper; + this.jsonUtils = jsonUtils; + } + + /** + * Validates whether the certain cookie is set. + * + * @param cookieName The name of the cookie to check presence. + */ + @Then("cookie with name `$cookieName` is set") + public void thenCookieWithNameIsSet(String cookieName) + { + Cookie cookie = cookieHelper.getCookie(cookieName); + softAssert.assertThat(String.format(COOKIE_IS_SET, cookieName), cookie, notNullValue()); + } + + /** + * Validates whether the certain cookie is not set. + * + * @param cookieName The name of the cookie to check absence. + */ + @Then("cookie with name `$cookieName` is not set") + public void thenCookieWithNameIsNotSet(String cookieName) + { + Cookie cookie = cookieHelper.getCookie(cookieName); + softAssert.assertThat(String.format("Cookie with the name '%s' is not set", cookieName), cookie, nullValue()); + } + + /** + * Adds the cookies provided in the input ExamplesTable. It's allowed to add the cookies for the current domain + * only: make sure the web browser is opened at the expected domain. + *

The cookie parameters to be defined in the ExamplesTable

+ *
    + *
  • cookieName - the name of the cookie to set
  • + *
  • cookieValue - the value of the cookie to set
  • + *
  • path - the path of the cookie to set
  • + *
+ *

Usage example:

+ * + *
When I set all cookies for current domain: + *
|cookieName |cookieValue |path | + *
|cookieAgreed |2 |/ | + *
+ * + * @param parameters The parameters of the cookies to set as ExamplesTable + */ + @When("I set all cookies for current domain:$parameters") + public void setAllCookies(ExamplesTable parameters) + { + String currentUrl = webApplicationConfiguration.getMainApplicationPageUrl().toString(); + Validate.isTrue(null != currentUrl, + "Unable to get current URL. Please make sure you've navigated to the right URL"); + parameters.getRows().forEach(row -> + cookieHelper.addCookie(row.get("cookieName"), row.get("cookieValue"), row.get("path"), currentUrl) + ); + } + + /** + * Finds the cookie by the name and saves its value to a variable. + * + * @param cookieName The name of the cookie to save the value. + * @param scopes The set (comma separated list of scopes e.g.: STORY, NEXT_BATCHES) of the variable + * scopes.
+ * Available scopes: + *
    + *
  • STEP - the variable will be available only within the step, + *
  • SCENARIO - the variable will be available only within the scenario, + *
  • STORY - the variable will be available within the whole story, + *
  • NEXT_BATCHES - the variable will be available starting from next batch + *
+ * @param variableName The variable name to save the cookie value. + */ + @When("I save value of cookie with name `$cookieName` to $scopes variable `$variableName`") + public void saveCookieIntoVariable(String cookieName, Set scopes, String variableName) + { + Cookie cookie = cookieHelper.getCookie(cookieName); + softAssert.assertThat(String.format(COOKIE_IS_SET, cookieName), cookie, notNullValue()); + variableContext.putVariable(scopes, variableName, cookieHelper.getValue(cookie)); + } + + /** + * Finds the cookie by the name and saves all its parameters as JSON to a variable. + * + * @param cookieName The name of the cookie to save. + * @param scopes The set (comma separated list of scopes e.g.: STORY, NEXT_BATCHES) of the variable + * scopes.
+ * Available scopes: + *
    + *
  • STEP - the variable will be available only within the step, + *
  • SCENARIO - the variable will be available only within the scenario, + *
  • STORY - the variable will be available within the whole story, + *
  • NEXT_BATCHES - the variable will be available starting from next batch + *
+ * @param variableName The variable name to save the cookie. + */ + @When("I save cookie with name `$cookieName` as JSON to $scopes variable `$variableName`") + public void saveCookieAsJson(String cookieName, Set scopes, String variableName) + { + Cookie cookie = cookieHelper.getCookie(cookieName); + softAssert.assertThat(String.format(COOKIE_IS_SET, cookieName), cookie, notNullValue()); + variableContext.putVariable(scopes, variableName, jsonUtils.toJson(cookie)); + } + + /** + * Removes all cookies from the current domain. + * + */ + @When("I remove all cookies from current domain") + public void removeAllCookies() + { + cookieHelper.deleteAllCookies(); + } + + /** + * Removes the certain cookie from the current domain. + * + * @param cookieName The name of the cookie to remove. + */ + @When("I remove cookie with name `$cookieName` from current domain") + public void removeCookie(String cookieName) + { + cookieHelper.deleteCookie(cookieName); + } +} diff --git a/vividus-plugin-web-app-playwright/src/main/resources/vividus-plugin/spring.xml b/vividus-plugin-web-app-playwright/src/main/resources/vividus-plugin/spring.xml index a9e9d64bcb..3a8f00d9b9 100644 --- a/vividus-plugin-web-app-playwright/src/main/resources/vividus-plugin/spring.xml +++ b/vividus-plugin-web-app-playwright/src/main/resources/vividus-plugin/spring.xml @@ -34,6 +34,7 @@ + @@ -45,6 +46,7 @@ + @@ -67,4 +69,6 @@ + + diff --git a/vividus-plugin-web-app-playwright/src/test/java/org/vividus/ui/web/playwright/steps/CookieStepsTests.java b/vividus-plugin-web-app-playwright/src/test/java/org/vividus/ui/web/playwright/steps/CookieStepsTests.java new file mode 100644 index 0000000000..c9ee357feb --- /dev/null +++ b/vividus-plugin-web-app-playwright/src/test/java/org/vividus/ui/web/playwright/steps/CookieStepsTests.java @@ -0,0 +1,130 @@ +/* + * Copyright 2019-2024 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.vividus.ui.web.playwright.steps; + +import com.microsoft.playwright.options.Cookie; +import org.jbehave.core.model.ExamplesTable; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; +import org.vividus.context.VariableContext; +import org.vividus.softassert.ISoftAssert; +import org.vividus.ui.web.configuration.WebApplicationConfiguration; +import org.vividus.ui.web.playwright.helper.CookieHelper; +import org.vividus.util.json.JsonUtils; +import org.vividus.variable.VariableScope; + +import java.net.URI; +import java.util.Set; + +import static org.mockito.ArgumentMatchers.argThat; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.*; + +@ExtendWith(MockitoExtension.class) +public class CookieStepsTests { + + private static final String NAME = "name"; + @Mock private Cookie cookie; + @Mock private CookieHelper cookieHelper; + @Mock private VariableContext variableContext; + @Mock private ISoftAssert softAssert; + @InjectMocks private CookieSteps cookieSteps; + @Mock private WebApplicationConfiguration webApplicationConfiguration; + @Mock private JsonUtils jsonUtils; + + @Test + void testThenCookieWithNameIsSet() + { + when(cookieHelper.getCookie(NAME)).thenReturn(cookie); + cookieSteps.thenCookieWithNameIsSet(NAME); + verifyCookieAssertion(cookie); + } + + @Test + void testThenCookieWithNameIsNotSet() + { + when(cookieHelper.getCookie(NAME)).thenReturn(cookie); + cookieSteps.thenCookieWithNameIsNotSet(NAME); + verify(softAssert).assertThat(eq("Cookie with the name '" + NAME + "' is not set"), eq(cookie), + argThat(m -> "null".equals(m.toString()))); + } + + @Test + void testSetAllCookies() + { + String testUrl = "https://www.vividus.org"; + URI uri = mock(); + when(webApplicationConfiguration.getMainApplicationPageUrl()).thenReturn(uri); + when(uri.toString()).thenReturn(testUrl); + + String tableAsString = "|cookieName|cookieValue|path|\n|hcpsid|1|/|\n|hcpsid|1|/|"; + ExamplesTable table = new ExamplesTable(tableAsString); + cookieSteps.setAllCookies(table); + verify(cookieHelper, times(2)).addCookie("hcpsid", "1", "/", testUrl); + } + + @Test + void shouldSaveCookieValueIntoVariableContext() + { + when(cookieHelper.getCookie(NAME)).thenReturn(cookie); + Set scopes = Set.of(VariableScope.SCENARIO); + String value = "value"; + when(cookieHelper.getValue(cookie)).thenReturn(value); + cookieSteps.saveCookieIntoVariable(NAME, scopes, NAME); + verify(variableContext).putVariable(scopes, NAME, value); + verifyCookieAssertion(cookie); + } + + @Test + void shouldConvertCookieToJsonAndSaveItToContext() + { + when(cookieHelper.getCookie(NAME)).thenReturn(cookie); + String cookieAsJson = "{\"path\": \"/index\"}"; + when(jsonUtils.toJson(cookie)).thenReturn(cookieAsJson); + Set scopes = Set.of(VariableScope.STEP); + + cookieSteps.saveCookieAsJson(NAME, scopes, NAME); + verify(variableContext).putVariable(scopes, NAME, cookieAsJson); + } + + @Test + void shouldRemoveAllCookies() + { + cookieSteps.removeAllCookies(); + var ordered = inOrder(cookieHelper); + ordered.verify(cookieHelper).deleteAllCookies(); + ordered.verifyNoMoreInteractions(); + } + + @Test + void shouldRemoveCookie() + { + cookieSteps.removeCookie(NAME); + var ordered = inOrder(cookieHelper); + ordered.verify(cookieHelper).deleteCookie(NAME); + ordered.verifyNoMoreInteractions(); + } + + private void verifyCookieAssertion(Cookie cookie) + { + verify(softAssert).assertThat(eq("Cookie with the name '" + NAME + "' is set"), eq(cookie), + argThat(m -> "not null".equals(m.toString()))); + } +} diff --git a/vividus-tests/src/main/resources/story/integration/CookieStepsPlaywright.story b/vividus-tests/src/main/resources/story/integration/CookieStepsPlaywright.story new file mode 100644 index 0000000000..87049e7b32 --- /dev/null +++ b/vividus-tests/src/main/resources/story/integration/CookieStepsPlaywright.story @@ -0,0 +1,16 @@ +Meta: + @epic vividus-plugin-web-app-playwright + +Scenario: Validate steps for cookie management in web application +Given I am on main application page +When I set all cookies for current domain: +|cookieName |cookieValue |path| +|cookieName1|cookieValue1|/ | +|cookieName2|cookieValue2|/ | +|cookieName3|cookieValue3|/ | +Then cookie with name `cookieName2` is set +When I remove cookie with name `cookieName2` from current domain +Then cookie with name `cookieName2` is not set +When I remove all cookies from current domain +Then cookie with name `cookieName1` is not set +Then cookie with name `cookieName3` is not set \ No newline at end of file