aboutsummaryrefslogtreecommitdiffstats
path: root/src/scenarios
diff options
context:
space:
mode:
authorkj_sh6042026-02-11 11:57:38 -0500
committerkj_sh6042026-02-11 11:57:38 -0500
commitd060ff5ca58e87e6dd1c6d93b97adbfd45f57f9b (patch)
treeaded1017253e8aa5b5c2996caf30630f8ed89c1f /src/scenarios
parentaa845e20842ecf93f7e69b03097dbc6508a70fc8 (diff)
refactor: move all to `src/` directoryHEADmaster
Diffstat (limited to 'src/scenarios')
-rw-r--r--src/scenarios/__init__.py1
-rw-r--r--src/scenarios/base.py82
-rw-r--r--src/scenarios/example.py72
3 files changed, 155 insertions, 0 deletions
diff --git a/src/scenarios/__init__.py b/src/scenarios/__init__.py
new file mode 100644
index 0000000..9f5de1c
--- /dev/null
+++ b/src/scenarios/__init__.py
@@ -0,0 +1 @@
+# scenarios/__init__.py
diff --git a/src/scenarios/base.py b/src/scenarios/base.py
new file mode 100644
index 0000000..f15a82f
--- /dev/null
+++ b/src/scenarios/base.py
@@ -0,0 +1,82 @@
+#!/usr/bin/env python3
+
+# scenarios/base.py - base scenario class
+
+# inherit from BaseScenario and override the `run()` method
+# to define your own load test behavior. that's it.
+
+import logging
+import time
+
+logger = logging.getLogger("loadtest.scenario")
+
+
+class BaseScenario:
+ """
+ base class for all load test scenarios.
+
+ subclass this and implement `run(page)` to define what
+ each virtual user does during the load test. the `page`
+ argument is a playwright Page object — you can navigate,
+ click, scrape, fill forms, whatever you want.
+
+ optionally override `setup(page)` and `teardown(page)`
+ for per-iteration init and cleanup.
+ """
+
+ name = "base"
+
+ def setup(self, page):
+ """
+ called BEFORE each iteration of `run()`.
+ override this if you need to do login, seed data, etc.
+ """
+ pass
+
+ def run(self, page):
+ """
+ the main scenario logic. this is what each virtual
+ user will execute on every iteration.
+
+ override this method in your subclass.
+
+ Args:
+ page: a playwright Page object.
+ """
+ raise NotImplementedError(
+ "you need to implement the run() method in your scenario. "
+ "check out scenarios/example.py for reference."
+ )
+
+ def teardown(self, page):
+ """
+ called AFTER each iteration of `run()`.
+ override this for cleanup, logging out, etc.
+ """
+ pass
+
+ def on_response(self, response):
+ """
+ optional hook — called on every HTTP response the page
+ receives during the scenario. useful for logging API
+ calls, checking status codes, etc.
+
+ override if you want response-level visibility.
+
+ Args:
+ response: a playwright Response object.
+ """
+ pass
+
+ def on_request(self, request):
+ """
+ optional hook — called on every HTTP request the page
+ makes during the scenario. useful for logging outgoing
+ requests.
+
+ override if you want request-level visibility.
+
+ Args:
+ request: a playwright Request object.
+ """
+ pass
diff --git a/src/scenarios/example.py b/src/scenarios/example.py
new file mode 100644
index 0000000..fd555ff
--- /dev/null
+++ b/src/scenarios/example.py
@@ -0,0 +1,72 @@
+#!/usr/bin/env python3
+
+# this is an example that shows how to write your own
+# scenario. copy this file, rename it, and modify the run()
+# method to do whatever you want.
+
+# the run() method receives a playwright Page object.
+# you can navigate, click, scrape text, fill forms,
+# take screenshots, assert content — the full playwright
+# API is at your disposal.
+
+import logging
+
+from scenarios.base import BaseScenario
+
+logger = logging.getLogger("loadtest.scenario.example")
+
+
+class ExampleScenario(BaseScenario):
+ """
+ example scenario that demonstrates:
+ - navigating to the target URL
+ - scraping page content
+ - clicking links / navigating around
+ - filling out a form
+ - grabbing data from the page
+
+ modify this to fit your actual load test needs.
+ """
+
+ name = "example"
+
+ def setup(self, page):
+ logger.debug("[setup] preparing for iteration...")
+
+ def run(self, page):
+ """
+ this is where the action happens. each virtual user
+ will execute this method once per iteration.
+ """
+
+ logger.info("[run] navigating to base URL...")
+ page.goto("/")
+ page.wait_for_load_state("networkidle")
+
+ title = page.title()
+ logger.info(f"[run] page title: {title}")
+
+ # python playwright code goes here - click links, fill forms, scrape content, etc.
+
+ logger.info("[run] scenario iteration complete.")
+
+ def teardown(self, page):
+ logger.debug("[teardown] cleaning up after iteration...")
+
+ def on_response(self, response):
+ """
+ log every HTTP response for visibility.
+ you can filter by URL pattern, status code, etc.
+ """
+ status = response.status
+ url = response.url
+ if status >= 400:
+ logger.warning(f"[response] {status} <- {url}")
+ else:
+ logger.debug(f"[response] {status} <- {url}")
+
+ def on_request(self, request):
+ """
+ log outgoing requests.
+ """
+ logger.debug(f"[request] {request.method} -> {request.url}") \ No newline at end of file