From a6b66d6f54e97afda5057ee244f45727e2e34097 Mon Sep 17 00:00:00 2001 From: Yauheni Hapanovich Date: Wed, 26 Jun 2024 20:43:30 +0300 Subject: [PATCH] Implement Cookie Steps code logic for Playwright --- .../pages/plugin-web-app-playwright.adoc | 2 + .../plugins/partials/web-cookie-steps.adoc | 129 +++++++++++++ vividus-extension-web-app/build.gradle | 1 + .../ui/web/action/IBaseCookieManager.java | 30 +++ .../ui/web/action/InetAddressUtils.java | 50 +++++ .../ui/web/action/InetAddressUtilsTests.java | 36 ++++ .../web/playwright/action/CookieManager.java | 83 +++++++++ .../ui/web/playwright/steps/CookieSteps.java | 176 ++++++++++++++++++ .../main/resources/vividus-plugin/spring.xml | 4 + .../playwright/action/CookieManagerTests.java | 126 +++++++++++++ .../playwright/steps/CookieStepsTests.java | 167 +++++++++++++++++ .../vividus/ui/web/action/CookieManager.java | 19 +- .../vividus/ui/web/action/ICookieManager.java | 14 +- 13 files changed, 808 insertions(+), 29 deletions(-) create mode 100644 docs/modules/plugins/partials/web-cookie-steps.adoc create mode 100644 vividus-extension-web-app/src/main/java/org/vividus/ui/web/action/IBaseCookieManager.java create mode 100644 vividus-extension-web-app/src/main/java/org/vividus/ui/web/action/InetAddressUtils.java create mode 100644 vividus-extension-web-app/src/test/java/org/vividus/ui/web/action/InetAddressUtilsTests.java create mode 100644 vividus-plugin-web-app-playwright/src/main/java/org/vividus/ui/web/playwright/action/CookieManager.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/action/CookieManagerTests.java create mode 100644 vividus-plugin-web-app-playwright/src/test/java/org/vividus/ui/web/playwright/steps/CookieStepsTests.java diff --git a/docs/modules/plugins/pages/plugin-web-app-playwright.adoc b/docs/modules/plugins/pages/plugin-web-app-playwright.adoc index 7470fb2fe1..7f6b1b8dfe 100644 --- a/docs/modules/plugins/pages/plugin-web-app-playwright.adoc +++ b/docs/modules/plugins/pages/plugin-web-app-playwright.adoc @@ -346,3 +346,5 @@ Then text `Modal Frame Example` exists ---- include::plugins:partial$ui-element-css-property-steps.adoc[] + +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..3e1a08098e --- /dev/null +++ b/docs/modules/plugins/partials/web-cookie-steps.adoc @@ -0,0 +1,129 @@ +=== 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]. + +[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-extension-web-app/build.gradle b/vividus-extension-web-app/build.gradle index 35d78ef6d0..92452bc7a1 100644 --- a/vividus-extension-web-app/build.gradle +++ b/vividus-extension-web-app/build.gradle @@ -2,6 +2,7 @@ project.description = 'VIVIDUS extension for web application testing plugins' dependencies { implementation project(':vividus-util') + implementation(group: 'com.google.guava', name: 'guava', version: '33.2.1-jre') testImplementation platform(group: 'org.junit', name: 'junit-bom', version: '5.10.2') testImplementation(group: 'org.junit.jupiter', name: 'junit-jupiter') diff --git a/vividus-extension-web-app/src/main/java/org/vividus/ui/web/action/IBaseCookieManager.java b/vividus-extension-web-app/src/main/java/org/vividus/ui/web/action/IBaseCookieManager.java new file mode 100644 index 0000000000..e895239d78 --- /dev/null +++ b/vividus-extension-web-app/src/main/java/org/vividus/ui/web/action/IBaseCookieManager.java @@ -0,0 +1,30 @@ +/* + * 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.action; + +public interface IBaseCookieManager +{ + void addCookie(String cookieName, String cookieValue, String path, String urlAsString); + + void deleteAllCookies(); + + void deleteCookie(String cookieName); + + T getCookie(String cookieName); + + S getCookies(); +} diff --git a/vividus-extension-web-app/src/main/java/org/vividus/ui/web/action/InetAddressUtils.java b/vividus-extension-web-app/src/main/java/org/vividus/ui/web/action/InetAddressUtils.java new file mode 100644 index 0000000000..74954cebfe --- /dev/null +++ b/vividus-extension-web-app/src/main/java/org/vividus/ui/web/action/InetAddressUtils.java @@ -0,0 +1,50 @@ +/* + * 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.action; + +import java.net.URI; + +import com.google.common.net.InetAddresses; +import com.google.common.net.InternetDomainName; + +public final class InetAddressUtils +{ + private static final String DOMAIN_PARTS_SEPARATOR = "."; + + private InetAddressUtils() + { + } + + /** + * Returns the domain of the URL. + * + * @param urlAsString String representation of the URL. + * @return The domain of the URL. + */ + public static String getDomain(String urlAsString) + { + String host = URI.create(urlAsString).getHost(); + return host.contains(DOMAIN_PARTS_SEPARATOR) && !InetAddresses.isInetAddress(host) + ? DOMAIN_PARTS_SEPARATOR + getTopDomain(host) + : host; + } + + private static String getTopDomain(String host) + { + return InternetDomainName.from(host).topPrivateDomain().toString(); + } +} diff --git a/vividus-extension-web-app/src/test/java/org/vividus/ui/web/action/InetAddressUtilsTests.java b/vividus-extension-web-app/src/test/java/org/vividus/ui/web/action/InetAddressUtilsTests.java new file mode 100644 index 0000000000..76803d0abe --- /dev/null +++ b/vividus-extension-web-app/src/test/java/org/vividus/ui/web/action/InetAddressUtilsTests.java @@ -0,0 +1,36 @@ +/* + * 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.action; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; + +class InetAddressUtilsTests +{ + @ParameterizedTest + @CsvSource({ + "https://www.domain.com, .domain.com", + "http://127.0.0.1:8080, 127.0.0.1", + "http://localhost:8080, localhost" + }) + void shouldGetDomain(String urlAsString, String domain) + { + assertEquals(domain, InetAddressUtils.getDomain(urlAsString)); + } +} diff --git a/vividus-plugin-web-app-playwright/src/main/java/org/vividus/ui/web/playwright/action/CookieManager.java b/vividus-plugin-web-app-playwright/src/main/java/org/vividus/ui/web/playwright/action/CookieManager.java new file mode 100644 index 0000000000..336249f25c --- /dev/null +++ b/vividus-plugin-web-app-playwright/src/main/java/org/vividus/ui/web/playwright/action/CookieManager.java @@ -0,0 +1,83 @@ +/* + * 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.action; + +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.action.IBaseCookieManager; +import org.vividus.ui.web.action.InetAddressUtils; +import org.vividus.ui.web.playwright.BrowserContextProvider; + +public class CookieManager implements IBaseCookieManager> +{ + private static final Logger LOGGER = LoggerFactory.getLogger(CookieManager.class); + + private final BrowserContextProvider browserContextProvider; + + public CookieManager(BrowserContextProvider browserContextProvider) + { + this.browserContextProvider = browserContextProvider; + } + + @Override + public void addCookie(String cookieName, String cookieValue, String path, String urlAsString) + { + String domain = InetAddressUtils.getDomain(urlAsString); + Cookie cookie = new Cookie(cookieName, cookieValue) + .setPath(path) + .setDomain(domain); + LOGGER.debug("Adding cookie: {}", cookie); + getBrowserContext().addCookies(List.of(cookie)); + } + + @Override + public void deleteAllCookies() + { + getBrowserContext().clearCookies(); + } + + @Override + public void deleteCookie(String cookieName) + { + getBrowserContext().clearCookies(new BrowserContext.ClearCookiesOptions().setName(cookieName)); + } + + @Override + public Cookie getCookie(String cookieName) + { + return getBrowserContext().cookies().stream() + .filter(cookie -> cookie.name.equals(cookieName)) + .findFirst() + .orElse(null); + } + + @Override + public List getCookies() + { + return getBrowserContext().cookies(); + } + + private BrowserContext getBrowserContext() + { + return browserContextProvider.get(); + } +} 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..5a7d08af0e --- /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.List; +import java.util.Optional; +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.action.IBaseCookieManager; +import org.vividus.ui.web.configuration.WebApplicationConfiguration; +import org.vividus.util.json.JsonUtils; +import org.vividus.variable.VariableScope; + +public class CookieSteps +{ + private static final String COOKIE_IS_SET = "Cookie with the name '%s' is set"; + + private final WebApplicationConfiguration webApplicationConfiguration; + private final VariableContext variableContext; + private final ISoftAssert softAssert; + private final IBaseCookieManager> cookieManager; + private final JsonUtils jsonUtils; + + public CookieSteps(VariableContext variableContext, WebApplicationConfiguration webApplicationConfiguration, + ISoftAssert softAssert, IBaseCookieManager> cookieManager, JsonUtils jsonUtils) + { + this.variableContext = variableContext; + this.webApplicationConfiguration = webApplicationConfiguration; + this.softAssert = softAssert; + this.cookieManager = cookieManager; + this.jsonUtils = jsonUtils; + } + + /** + * Validates whether the certain cookie is set. + * + * @param cookieName The name of the cookie to check presence. + * @return The cookie if present + */ + @Then("cookie with name `$cookieName` is set") + public Optional thenCookieWithNameIsSet(String cookieName) + { + Cookie cookie = cookieManager.getCookie(cookieName); + softAssert.assertThat(String.format(COOKIE_IS_SET, cookieName), cookie, notNullValue()); + return Optional.ofNullable(cookie); + } + + /** + * 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 = cookieManager.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. + *

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(currentUrl != null, + "Unable to get current URL. Please make sure you've navigated to the right URL"); + parameters.getRows().forEach(row -> + cookieManager.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) + { + thenCookieWithNameIsSet(cookieName) + .ifPresent(cookie -> variableContext.putVariable(scopes, variableName, cookie.value)); + } + + /** + * 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) + { + Optional.ofNullable(cookieManager.getCookie(cookieName)) + .ifPresent(cookie -> 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() + { + cookieManager.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) + { + cookieManager.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 3f32bd0b6f..bbac4e668b 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 @@ -30,12 +30,15 @@ + + + @@ -47,6 +50,7 @@ + diff --git a/vividus-plugin-web-app-playwright/src/test/java/org/vividus/ui/web/playwright/action/CookieManagerTests.java b/vividus-plugin-web-app-playwright/src/test/java/org/vividus/ui/web/playwright/action/CookieManagerTests.java new file mode 100644 index 0000000000..b621181b28 --- /dev/null +++ b/vividus-plugin-web-app-playwright/src/test/java/org/vividus/ui/web/playwright/action/CookieManagerTests.java @@ -0,0 +1,126 @@ +/* + * 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.action; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import java.util.List; + +import com.microsoft.playwright.BrowserContext; +import com.microsoft.playwright.options.Cookie; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; +import org.mockito.ArgumentCaptor; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; +import org.vividus.ui.web.playwright.BrowserContextProvider; + +@ExtendWith(MockitoExtension.class) +class CookieManagerTests +{ + private static final String PATH = "/"; + private static final String ZERO = "0"; + private static final String COOKIE_NAME = "name"; + private static final String COOKIE_VALUE = "cookieValue"; + private static final String DOMAIN = "https://www.domain.com"; + + @Mock private BrowserContextProvider browserContextProvider; + @Mock private BrowserContext browserContext; + @InjectMocks private CookieManager cookieManager; + + @Test + void shouldDeleteAllCookies() + { + when(browserContextProvider.get()).thenReturn(browserContext); + cookieManager.deleteAllCookies(); + verify(browserContext).clearCookies(); + } + + @Test + void shouldDeleteCookie() + { + ArgumentCaptor clearCookiesOptionsCaptor = ArgumentCaptor.captor(); + when(browserContextProvider.get()).thenReturn(browserContext); + cookieManager.deleteCookie(COOKIE_NAME); + verify(browserContext).clearCookies(clearCookiesOptionsCaptor.capture()); + BrowserContext.ClearCookiesOptions clearCookiesOptions = clearCookiesOptionsCaptor.getValue(); + assertEquals(COOKIE_NAME, clearCookiesOptions.name); + } + + @ParameterizedTest + @CsvSource({ + "https://www.domain.com, .domain.com", + "http://localhost:8080, localhost", + "http://test.topdomain.com/test/test, .topdomain.com", + "http://testproduct:80/test, testproduct", + "http://127.0.0.1:8080, 127.0.0.1" + }) + void shouldAddCookie(String urlAsString, String domain) + { + ArgumentCaptor> cookieCaptor = ArgumentCaptor.captor(); + when(browserContextProvider.get()).thenReturn(browserContext); + cookieManager.addCookie(COOKIE_NAME, ZERO, PATH, urlAsString); + verify(browserContext).addCookies(cookieCaptor.capture()); + + Cookie cookie = cookieCaptor.getValue().getFirst(); + assertEquals(COOKIE_NAME, cookie.name); + assertEquals(ZERO, cookie.value); + assertEquals(PATH, cookie.path); + assertEquals(domain, cookie.domain); + } + + @Test + void shouldGetCookie() + { + when(browserContextProvider.get()).thenReturn(browserContext); + Cookie cookie = createCookie(); + when(browserContext.cookies()).thenReturn(List.of(cookie)); + assertEquals(cookie, cookieManager.getCookie(COOKIE_NAME)); + } + + @Test + void shouldGetNullCookie() + { + when(browserContextProvider.get()).thenReturn(browserContext); + Cookie cookie = createCookie(); + when(browserContext.cookies()).thenReturn(List.of(cookie)); + assertNull(cookieManager.getCookie("INCORRECT_NAME")); + } + + @Test + void shouldGetCookies() + { + when(browserContextProvider.get()).thenReturn(browserContext); + List expectedCookies = List.of(createCookie()); + when(browserContext.cookies()).thenReturn(expectedCookies); + assertEquals(expectedCookies, cookieManager.getCookies()); + } + + private Cookie createCookie() + { + return new Cookie(COOKIE_NAME, COOKIE_VALUE) + .setPath(PATH) + .setDomain(DOMAIN); + } +} 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..a14e014033 --- /dev/null +++ b/vividus-plugin-web-app-playwright/src/test/java/org/vividus/ui/web/playwright/steps/CookieStepsTests.java @@ -0,0 +1,167 @@ +/* + * 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.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.mockito.ArgumentMatchers.argThat; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.inOrder; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoInteractions; +import static org.mockito.Mockito.when; + +import java.net.URI; +import java.util.Set; + +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.action.CookieManager; +import org.vividus.util.json.JsonUtils; +import org.vividus.variable.VariableScope; + +@ExtendWith(MockitoExtension.class) +class CookieStepsTests +{ + private static final String NAME = "name"; + private static final String COOKIE_WITH_NAME_TEXT = "Cookie with the name '"; + @Mock private Cookie cookie; + @Mock private CookieManager cookieManager; + @Mock private VariableContext variableContext; + @Mock private ISoftAssert softAssert; + @Mock private WebApplicationConfiguration webApplicationConfiguration; + @Mock private JsonUtils jsonUtils; + @InjectMocks private CookieSteps cookieSteps; + + @Test + void testThenCookieWithNameIsSet() + { + when(cookieManager.getCookie(NAME)).thenReturn(cookie); + cookieSteps.thenCookieWithNameIsSet(NAME); + verifyCookieAssertion(cookie); + } + + @Test + void testThenCookieWithNameIsNotSet() + { + when(cookieManager.getCookie(NAME)).thenReturn(cookie); + cookieSteps.thenCookieWithNameIsNotSet(NAME); + verify(softAssert).assertThat(eq(COOKIE_WITH_NAME_TEXT + 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(cookieManager, times(2)).addCookie("hcpsid", "1", "/", testUrl); + } + + @Test + void shouldSaveCookieValueIntoVariableContext() + { + String value = "value"; + Cookie newCookie = new Cookie(NAME, value); + when(cookieManager.getCookie(NAME)).thenReturn(newCookie); + Set scopes = Set.of(VariableScope.SCENARIO); + + cookieSteps.saveCookieIntoVariable(NAME, scopes, NAME); + verify(variableContext).putVariable(scopes, NAME, value); + verifyCookieAssertion(newCookie); + } + + @Test + void shouldConvertCookieToJsonAndSaveItToContext() + { + when(cookieManager.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(cookieManager); + ordered.verify(cookieManager).deleteAllCookies(); + ordered.verifyNoMoreInteractions(); + } + + @Test + void shouldRemoveCookie() + { + cookieSteps.removeCookie(NAME); + var ordered = inOrder(cookieManager); + ordered.verify(cookieManager).deleteCookie(NAME); + ordered.verifyNoMoreInteractions(); + } + + @Test + void shouldThrowAnExceptionIfCurrentURLIsNotDefined() + { + ExamplesTable table = mock(); + URI uri = mock(); + when(webApplicationConfiguration.getMainApplicationPageUrl()).thenReturn(uri); + when(uri.toString()).thenReturn(null); + IllegalArgumentException iae = + assertThrows(IllegalArgumentException.class, () -> cookieSteps.setAllCookies(table)); + assertEquals("Unable to get current URL. Please make sure you've navigated to the right URL", iae.getMessage()); + } + + @Test + void shouldNotSaveNotExistingCookieAndRecordAssertion() + { + cookieSteps.saveCookieIntoVariable(NAME, Set.of(VariableScope.SCENARIO), NAME); + verifyNoInteractions(variableContext); + verifyCookieAssertion(null); + } + + @Test + void shouldNotConvertNorSaveIfNoCookieReturnedByCookieHelper() + { + cookieSteps.saveCookieAsJson(NAME, Set.of(VariableScope.STEP), NAME); + verifyNoInteractions(jsonUtils, variableContext); + } + + private void verifyCookieAssertion(Cookie cookie) + { + verify(softAssert).assertThat(eq(COOKIE_WITH_NAME_TEXT + NAME + "' is set"), eq(cookie), + argThat(m -> "not null".equals(m.toString()))); + } +} diff --git a/vividus-plugin-web-app/src/main/java/org/vividus/ui/web/action/CookieManager.java b/vividus-plugin-web-app/src/main/java/org/vividus/ui/web/action/CookieManager.java index 427eae4be5..0f8dc1dd24 100644 --- a/vividus-plugin-web-app/src/main/java/org/vividus/ui/web/action/CookieManager.java +++ b/vividus-plugin-web-app/src/main/java/org/vividus/ui/web/action/CookieManager.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2023 the original author or authors. + * 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. @@ -16,14 +16,10 @@ package org.vividus.ui.web.action; -import java.net.URI; import java.util.Date; import java.util.Optional; import java.util.Set; -import com.google.common.net.InetAddresses; -import com.google.common.net.InternetDomainName; - import org.apache.hc.client5.http.cookie.CookieStore; import org.apache.hc.client5.http.impl.cookie.BasicClientCookie; import org.openqa.selenium.Cookie; @@ -39,18 +35,12 @@ public class CookieManager implements ICookieManager { private static final Logger LOGGER = LoggerFactory.getLogger(CookieManager.class); - private static final String DOMAIN_PARTS_SEPARATOR = "."; - @Inject private IWebDriverProvider webDriverProvider; @Override public void addCookie(String cookieName, String cookieValue, String path, String urlAsString) { - String host = URI.create(urlAsString).getHost(); - String domain = host.contains(DOMAIN_PARTS_SEPARATOR) && !InetAddresses.isInetAddress(host) - ? DOMAIN_PARTS_SEPARATOR + getTopDomain(host) - : host; - + String domain = InetAddressUtils.getDomain(urlAsString); Cookie cookie = new Cookie.Builder(cookieName, cookieValue) .domain(domain) .path(path) @@ -59,11 +49,6 @@ public void addCookie(String cookieName, String cookieValue, String path, String getOptions().addCookie(cookie); } - private static String getTopDomain(String host) - { - return InternetDomainName.from(host).topPrivateDomain().toString(); - } - @Override public void deleteAllCookies() { diff --git a/vividus-plugin-web-app/src/main/java/org/vividus/ui/web/action/ICookieManager.java b/vividus-plugin-web-app/src/main/java/org/vividus/ui/web/action/ICookieManager.java index 20c531d164..f20190b45a 100644 --- a/vividus-plugin-web-app/src/main/java/org/vividus/ui/web/action/ICookieManager.java +++ b/vividus-plugin-web-app/src/main/java/org/vividus/ui/web/action/ICookieManager.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2023 the original author or authors. + * 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. @@ -21,17 +21,7 @@ import org.apache.hc.client5.http.cookie.CookieStore; import org.openqa.selenium.Cookie; -public interface ICookieManager +public interface ICookieManager extends IBaseCookieManager> { - void addCookie(String cookieName, String cookieValue, String path, String urlAsString); - - void deleteAllCookies(); - - void deleteCookie(String cookieName); - - Cookie getCookie(String cookieName); - - Set getCookies(); - CookieStore getCookiesAsHttpCookieStore(); }