diff --git a/docs/modules/plugins/pages/plugin-rest-api.adoc b/docs/modules/plugins/pages/plugin-rest-api.adoc
index 1c64deb8e4..2b55342881 100644
--- a/docs/modules/plugins/pages/plugin-rest-api.adoc
+++ b/docs/modules/plugins/pages/plugin-rest-api.adoc
@@ -36,6 +36,20 @@ a|`true`
|`false`
|Enable logging of HTTP request/response headers and bodies (applied to the following content types only: `text/*`, `application/json`, `application/xml`)
+|`rest-api.http.cookie-store-level`
+a|`global` +
+`story` +
+`scenario` +
+`step`
+|`global`
+a|Configure the level of cookie storage:
+
+* `global` - cookies are stored globally and are accessible across the entire suite from all threads: cookies set in
+one scenario are available and reused in all subsequent scenarios and stories.
+* `story` - cookies are reused within the scope of a single story and are cleared upon its completion.
+* `scenario` - cookies are reused within the scope of a single scenario and are cleared upon its completion.
+* `step` - cookies are cleared after each executed step.
+
|===
See xref:configuration:tests-configuration.adoc#_http_configuration[HTTP configuration] for more fine-grained control over the HTTP interactions.
diff --git a/vividus-plugin-rest-api/src/main/java/org/vividus/http/CookieStepMonitor.java b/vividus-plugin-rest-api/src/main/java/org/vividus/http/CookieStepMonitor.java
new file mode 100644
index 0000000000..9d3253b11c
--- /dev/null
+++ b/vividus-plugin-rest-api/src/main/java/org/vividus/http/CookieStepMonitor.java
@@ -0,0 +1,40 @@
+/*
+ * 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.http;
+
+import java.lang.reflect.Method;
+
+import org.jbehave.core.steps.NullStepMonitor;
+
+public class CookieStepMonitor extends NullStepMonitor
+{
+ private final CookieStoreProvider cookieStoreProvider;
+
+ public CookieStepMonitor(CookieStoreProvider cookieStoreProvider)
+ {
+ this.cookieStoreProvider = cookieStoreProvider;
+ }
+
+ @Override
+ public void afterPerforming(String step, boolean dryRun, Method method)
+ {
+ if (!dryRun)
+ {
+ cookieStoreProvider.resetStepCookies();
+ }
+ }
+}
diff --git a/vividus-plugin-rest-api/src/main/java/org/vividus/http/CookieStoreLevel.java b/vividus-plugin-rest-api/src/main/java/org/vividus/http/CookieStoreLevel.java
index 3c713dcfcb..5ddea9f27e 100644
--- a/vividus-plugin-rest-api/src/main/java/org/vividus/http/CookieStoreLevel.java
+++ b/vividus-plugin-rest-api/src/main/java/org/vividus/http/CookieStoreLevel.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2019-2020 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.
@@ -20,5 +20,6 @@ public enum CookieStoreLevel
{
GLOBAL,
STORY,
- SCENARIO
+ SCENARIO,
+ STEP
}
diff --git a/vividus-plugin-rest-api/src/main/java/org/vividus/http/CookieStoreProvider.java b/vividus-plugin-rest-api/src/main/java/org/vividus/http/CookieStoreProvider.java
index d1e2a326fc..8573a52c41 100644
--- a/vividus-plugin-rest-api/src/main/java/org/vividus/http/CookieStoreProvider.java
+++ b/vividus-plugin-rest-api/src/main/java/org/vividus/http/CookieStoreProvider.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.
@@ -39,6 +39,14 @@ public CookieStore getCookieStore()
return cookieStore;
}
+ public void resetStepCookies()
+ {
+ if (cookieStoreLevel == CookieStoreLevel.STEP)
+ {
+ cookieStore.clear();
+ }
+ }
+
@AfterScenario
public void resetScenarioCookies()
{
diff --git a/vividus-plugin-rest-api/src/main/resources/vividus-plugin/spring.xml b/vividus-plugin-rest-api/src/main/resources/vividus-plugin/spring.xml
index 2ee8023575..79963a5ca3 100644
--- a/vividus-plugin-rest-api/src/main/resources/vividus-plugin/spring.xml
+++ b/vividus-plugin-rest-api/src/main/resources/vividus-plugin/spring.xml
@@ -131,4 +131,6 @@
+
+
diff --git a/vividus-plugin-rest-api/src/test/java/org/vividus/http/CookieStepMonitorTests.java b/vividus-plugin-rest-api/src/test/java/org/vividus/http/CookieStepMonitorTests.java
new file mode 100644
index 0000000000..83265a4a57
--- /dev/null
+++ b/vividus-plugin-rest-api/src/test/java/org/vividus/http/CookieStepMonitorTests.java
@@ -0,0 +1,47 @@
+/*
+ * 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.http;
+
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoInteractions;
+
+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;
+
+@ExtendWith(MockitoExtension.class)
+class CookieStepMonitorTests
+{
+ @Mock private CookieStoreProvider cookieStoreProvider;
+ @InjectMocks private CookieStepMonitor cookieStepMonitor;
+
+ @Test
+ void shouldClearCookiesAfterStep()
+ {
+ cookieStepMonitor.afterPerforming(null, false, null);
+ verify(cookieStoreProvider).resetStepCookies();
+ }
+
+ @Test
+ void shouldNotClearCookiesAfterStep()
+ {
+ cookieStepMonitor.afterPerforming(null, true, null);
+ verifyNoInteractions(cookieStoreProvider);
+ }
+}
diff --git a/vividus-plugin-rest-api/src/test/java/org/vividus/http/CookieStoreProviderTests.java b/vividus-plugin-rest-api/src/test/java/org/vividus/http/CookieStoreProviderTests.java
index f3eddba3e8..1fbad08a17 100644
--- a/vividus-plugin-rest-api/src/test/java/org/vividus/http/CookieStoreProviderTests.java
+++ b/vividus-plugin-rest-api/src/test/java/org/vividus/http/CookieStoreProviderTests.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.
@@ -35,7 +35,8 @@ class CookieStoreProviderTests
@CsvSource({
"GLOBAL, org.apache.hc.client5.http.cookie.BasicCookieStore",
"STORY, org.vividus.http.client.ThreadedBasicCookieStore",
- "SCENARIO, org.vividus.http.client.ThreadedBasicCookieStore"
+ "SCENARIO, org.vividus.http.client.ThreadedBasicCookieStore",
+ "STEP, org.vividus.http.client.ThreadedBasicCookieStore"
})
void shouldCreateCookieStore(CookieStoreLevel cookieStoreLevel, Class> clazz)
{
@@ -43,6 +44,15 @@ void shouldCreateCookieStore(CookieStoreLevel cookieStoreLevel, Class> clazz)
assertEquals(clazz, cookieStoreProvider.getCookieStore().getClass());
}
+ @ParameterizedTest
+ @EnumSource(names = "STEP", mode = Mode.EXCLUDE)
+ void shouldNotClearCookieStoreAfterStep(CookieStoreLevel cookieStoreLevel)
+ {
+ CookieStoreProvider cookieStoreProvider = createProviderWithCookie(cookieStoreLevel);
+ cookieStoreProvider.resetStepCookies();
+ assertEquals(List.of(COOKIE), cookieStoreProvider.getCookieStore().getCookies());
+ }
+
@ParameterizedTest
@EnumSource(names = "SCENARIO", mode = Mode.EXCLUDE)
void shouldNotClearCookieStoreAfterScenario(CookieStoreLevel cookieStoreLevel)
@@ -61,6 +71,14 @@ void shouldNotClearCookieStoreAfterStory(CookieStoreLevel cookieStoreLevel)
assertEquals(List.of(COOKIE), cookieStoreProvider.getCookieStore().getCookies());
}
+ @Test
+ void shouldClearCookieStoreAfterStep()
+ {
+ CookieStoreProvider cookieStoreProvider = createProviderWithCookie(CookieStoreLevel.STEP);
+ cookieStoreProvider.resetStepCookies();
+ assertEquals(List.of(), cookieStoreProvider.getCookieStore().getCookies());
+ }
+
@Test
void shouldClearCookieStoreAfterScenario()
{