klab-pytest-toolkit-web 0.0.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,178 @@
1
+ # Created by https://www.toptal.com/developers/gitignore/api/python
2
+ # Edit at https://www.toptal.com/developers/gitignore?templates=python
3
+
4
+ ### Custom ###
5
+ pytest.xml
6
+ pytest-coverage.txt
7
+ tmp/
8
+
9
+ ### Python ###
10
+ # Byte-compiled / optimized / DLL files
11
+ __pycache__/
12
+ *.py[cod]
13
+ *$py.class
14
+
15
+ # Distribution / packaging
16
+ .Python
17
+ build/
18
+ develop-eggs/
19
+ dist/
20
+ downloads/
21
+ eggs/
22
+ .eggs/
23
+ lib/
24
+ lib64/
25
+ parts/
26
+ sdist/
27
+ var/
28
+ wheels/
29
+ share/python-wheels/
30
+ *.egg-info/
31
+ .installed.cfg
32
+ *.egg
33
+ MANIFEST
34
+
35
+ # PyInstaller
36
+ # Usually these files are written by a python script from a template
37
+ # before PyInstaller builds the exe, so as to inject date/other infos into it.
38
+ *.manifest
39
+ *.spec
40
+
41
+ # Installer logs
42
+ pip-log.txt
43
+ pip-delete-this-directory.txt
44
+
45
+ # Unit test / coverage reports
46
+ htmlcov/
47
+ .tox/
48
+ .nox/
49
+ .coverage
50
+ .coverage.*
51
+ .cache
52
+ nosetests.xml
53
+ coverage.xml
54
+ *.cover
55
+ *.py,cover
56
+ .hypothesis/
57
+ .pytest_cache/
58
+ cover/
59
+
60
+ # Translations
61
+ *.mo
62
+ *.pot
63
+
64
+ # Django stuff:
65
+ *.log
66
+ local_settings.py
67
+ db.sqlite3
68
+ db.sqlite3-journal
69
+
70
+ # Flask stuff:
71
+ instance/
72
+ .webassets-cache
73
+
74
+ # Scrapy stuff:
75
+ .scrapy
76
+
77
+ # Sphinx documentation
78
+ docs/_build/
79
+
80
+ # PyBuilder
81
+ .pybuilder/
82
+ target/
83
+
84
+ # Jupyter Notebook
85
+ .ipynb_checkpoints
86
+
87
+ # IPython
88
+ profile_default/
89
+ ipython_config.py
90
+
91
+ # pyenv
92
+ # For a library or package, you might want to ignore these files since the code is
93
+ # intended to run in multiple environments; otherwise, check them in:
94
+ # .python-version
95
+
96
+ # pipenv
97
+ # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
98
+ # However, in case of collaboration, if having platform-specific dependencies or dependencies
99
+ # having no cross-platform support, pipenv may install dependencies that don't work, or not
100
+ # install all needed dependencies.
101
+ #Pipfile.lock
102
+
103
+ # poetry
104
+ # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
105
+ # This is especially recommended for binary packages to ensure reproducibility, and is more
106
+ # commonly ignored for libraries.
107
+ # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
108
+ #poetry.lock
109
+
110
+ # pdm
111
+ # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
112
+ #pdm.lock
113
+ # pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
114
+ # in version control.
115
+ # https://pdm.fming.dev/#use-with-ide
116
+ .pdm.toml
117
+
118
+ # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
119
+ __pypackages__/
120
+
121
+ # Celery stuff
122
+ celerybeat-schedule
123
+ celerybeat.pid
124
+
125
+ # SageMath parsed files
126
+ *.sage.py
127
+
128
+ # Environments
129
+ .env
130
+ .venv
131
+ env/
132
+ venv/
133
+ ENV/
134
+ env.bak/
135
+ venv.bak/
136
+
137
+ # Spyder project settings
138
+ .spyderproject
139
+ .spyproject
140
+
141
+ # Rope project settings
142
+ .ropeproject
143
+
144
+ # mkdocs documentation
145
+ /site
146
+
147
+ # mypy
148
+ .mypy_cache/
149
+ .dmypy.json
150
+ dmypy.json
151
+
152
+ # Pyre type checker
153
+ .pyre/
154
+
155
+ # pytype static type analyzer
156
+ .pytype/
157
+
158
+ # Cython debug symbols
159
+ cython_debug/
160
+
161
+ # PyCharm
162
+ # JetBrains specific template is maintained in a separate JetBrains.gitignore that can
163
+ # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
164
+ # and can be added to the global gitignore or merged into this file. For a more nuclear
165
+ # option (not recommended) you can uncomment the following to ignore the entire idea folder.
166
+ #.idea/
167
+
168
+ ### Python Patch ###
169
+ # Poetry local configuration file - https://python-poetry.org/docs/configuration/#local-configuration
170
+ poetry.toml
171
+
172
+ # ruff
173
+ .ruff_cache/
174
+
175
+ # LSP config files
176
+ pyrightconfig.json
177
+
178
+ # End of https://www.toptal.com/developers/gitignore/api/python
@@ -0,0 +1,235 @@
1
+ Metadata-Version: 2.4
2
+ Name: klab-pytest-toolkit-web
3
+ Version: 0.0.0
4
+ Summary: Pytest web fixtures for the Klab Pytest Toolkit
5
+ Project-URL: Changelog, https://github.com/klab365/klab-pytest-toolkit/blob/main/CHANGELOG.md
6
+ Project-URL: Repository, https://github.com/klab365/klab-pytest-toolkit
7
+ Project-URL: Issues, https://github.com/klab365/klab-pytest-toolkit/issues
8
+ Author-email: Burak Kizilkaya <burak.kizilkaya@outlook.com>
9
+ License-Expression: MIT
10
+ Classifier: Development Status :: 3 - Alpha
11
+ Classifier: Intended Audience :: Developers
12
+ Classifier: License :: OSI Approved :: MIT License
13
+ Classifier: Programming Language :: Python :: 3
14
+ Requires-Python: <4,>=3.11
15
+ Requires-Dist: grpcio-reflection>=1.66.0
16
+ Requires-Dist: grpcio-tools>=1.66.0
17
+ Requires-Dist: grpcio>=1.66.0
18
+ Requires-Dist: jsonschema>=4.25.1
19
+ Requires-Dist: playwright>=1.57.0
20
+ Requires-Dist: pytest>=8.3.5
21
+ Requires-Dist: requests>=2.32.5
22
+ Description-Content-Type: text/markdown
23
+
24
+ # Klab Pytest Toolkit - Web Fixtures
25
+
26
+ Custom pytest fixtures for web testing.
27
+ The goal is to allow testers to easily test web applications (html/json/rest api) with reusable components.
28
+
29
+ At the moment the package provides the following fixtures:
30
+
31
+ - `response_validator_factory`: Factory for create JSON response validator instances with custom configurations.
32
+ - `api_client_factory`: Factory for create different API client instances.
33
+ - REST API client for making HTTP requests to RESTful services.
34
+ - `web_client_factory`: Factory to create web client instances for browser automation
35
+ - Playwright-based web client for end-to-end testing of web applications.
36
+
37
+ ## Installation
38
+
39
+ ```bash
40
+ pip install klab-pytest-toolkit-web
41
+ ```
42
+
43
+ ## Usage
44
+
45
+ ### JSON Response Validator
46
+
47
+ **Create the fixture**
48
+
49
+ The factory class `ResponseValidatorFactory` is already provided as a pytest fixture `response_validator_factory`.
50
+
51
+ ```python
52
+ @pytest.fixture
53
+ def json_validator_user_schema(response_validator_factory) -> JsonResponseValidator:
54
+ """Fixture to provide a JSON response validator for user schema."""
55
+ user_schema = {
56
+ "type": "object",
57
+ "properties": {
58
+ "id": {"type": "integer"},
59
+ "name": {"type": "string"},
60
+ },
61
+ "required": ["id", "name"]
62
+ }
63
+ return response_validator_factory.create_json_validator(schema=user_schema)
64
+ ```
65
+
66
+ **Functions**
67
+
68
+ The validator contains one main function to validate a response against the schema. Below is an example of how to use the validator in a test.
69
+
70
+ ```python
71
+ def test_user_api(json_validator_user_schema):
72
+ """Test user API response validation."""
73
+ response_data = {
74
+ "id": 1,
75
+ "name": "John Doe"
76
+ }
77
+ assert json_validator_user_schema.validate_response(response_data)
78
+ ```
79
+
80
+ ### REST API Client
81
+
82
+ **Create the fixture**
83
+
84
+ The factory class `ApiClientFactory` is already provided as a pytest fixture `api_client_factory`.
85
+ To pass the url or other header information, you can pass this as environment variables or configure directly in the fixture.
86
+ Below is an example of creating a REST API client fixture from a testcontainer url.
87
+
88
+ ```python
89
+
90
+ @pytest.fixture(scope="session")
91
+ def httpbin_container():
92
+ """Fixture to provide an HTTPBin container for testing."""
93
+
94
+ with DockerContainer("kennethreitz/httpbin:latest") as httpbin:
95
+ httpbin.with_exposed_ports(80)
96
+ httpbin.waiting_for(HttpWaitStrategy(path="/get", port=80).for_status_code(200))
97
+ httpbin.start()
98
+ port = httpbin.get_exposed_port(80)
99
+ base_url = f"http://localhost:{port}"
100
+ yield base_url
101
+
102
+ @pytest.fixture
103
+ def rest_api_client(api_client_factory, httpbin_container) -> RestApiClient:
104
+ """Fixture to provide a REST API client."""
105
+ return api_client_factory.create_rest_client(base_url=httpbin_container)
106
+ ```
107
+
108
+ **Functions**
109
+
110
+ The REST API client provides functions to make HTTP requests. These are some examples:
111
+
112
+ ```python
113
+ def test_get_request(rest_api_client: RestApiClient):
114
+ """Test basic GET request with query parameters."""
115
+ response = rest_api_client.get("/get", params={"test": "value"})
116
+
117
+ assert response.status_code == 200
118
+ json_data = response.json()
119
+ assert json_data["args"]["test"] == "value"
120
+
121
+ def test_post_request(rest_api_client: RestApiClient):
122
+ """Test basic POST request with JSON body."""
123
+ response = rest_api_client.post("/post", payload={"key": "value"})
124
+
125
+ assert response.status_code == 200
126
+ json_data = response.json()
127
+ assert json_data["json"]["key"] == "value"
128
+
129
+ def test_update_request(rest_api_client: RestApiClient):
130
+ """Test basic PUT request with JSON body."""
131
+ response = rest_api_client.put("/put", payload={"update": "data"})
132
+
133
+ assert response.status_code == 200
134
+ json_data = response.json()
135
+ assert json_data["json"]["update"] == "data"
136
+
137
+ def test_delete_request(rest_api_client: RestApiClient):
138
+ """Test basic DELETE request."""
139
+ response = rest_api_client.delete("/delete")
140
+
141
+ assert response.status_code == 200
142
+ json_data = response.json()
143
+ assert json_data["url"].endswith("/delete")
144
+ ```
145
+
146
+ ### gRPC Client
147
+
148
+ **Create the fixture**
149
+
150
+ The factory class `ApiClientFactory` is already provided as a pytest fixture `api_client_factory`.
151
+ You can create a gRPC client fixture as shown below:
152
+
153
+ ```python
154
+ @pytest.fixture
155
+ def grpc_client(api_client_factory) -> GrpcClient:
156
+ """Fixture to provide a gRPC client."""
157
+ return api_client_factory.create_grpc_client(
158
+ target="localhost:50051",
159
+ proto_file="path/to/your/service.proto"
160
+ )
161
+ ```
162
+
163
+ **Functions**
164
+
165
+ The `GrpcClient` provides gRPC call functionality by dynamically invoking methods defined in the provided proto file. It is imported the that the proto file defines a service with methods like `GetUser`. You will not get any code completion in your IDE since the methods are dynamically resolved at runtime, but you get error handling if the method does not exist.
166
+
167
+ ```python
168
+ def test_grpc_get_user(grpc_client: GrpcClient):
169
+ """Test gRPC GetUser call."""
170
+ response = grpc_client.GetUser(id=123)
171
+
172
+ assert response.id == 123
173
+ assert response.name == "John Doe"
174
+ ```
175
+
176
+ ### Playwright Web Client
177
+
178
+ **Create the fixture**
179
+
180
+ The factory class `WebClientFactory` is already provided as a pytest fixture `web_client_factory`.
181
+ For playwright, you might install the browsers first by running `playwright install` in your environment.
182
+ You can create a Playwright web client fixture as shown below:
183
+
184
+ ```python
185
+ @pytest.fixture
186
+ def web_client(web_client_factory) -> PlaywrightWebClient:
187
+ """Fixture to provide a Playwright web client."""
188
+ with web_client_factory.create_client(client_type="playwright", headless=True) as client:
189
+ yield client
190
+ ```
191
+
192
+ **Functions**
193
+
194
+ The `WebClient` provides a variety of functions for browser automation. Refer to the api of the instance.
195
+ Here are some examples of common operations:
196
+
197
+ ```python
198
+ def test_navigate_and_click(web_client):
199
+ """Test navigation and clicking a button."""
200
+ web_client.navigate_to("https://example.com")
201
+ web_client.click("#start-button")
202
+ assert web_client.get_text("#result") == "Started"
203
+
204
+ def test_form_submission(web_client):
205
+ """Test form submission."""
206
+ web_client.navigate_to("https://example.com/form")
207
+ web_client.fill_input("#name", "Test User")
208
+ web_client.fill_input("#email", "max@muster.com")
209
+ web_client.click("#submit-button")
210
+ assert web_client.get_text("#confirmation") == "Thank you for your submission!"
211
+
212
+ def test_wait_for_element(web_client):
213
+ """Test waiting for an element to appear."""
214
+ web_client.navigate_to("https://example.com/dynamic")
215
+ web_client.wait_for_element("#dynamic-content", timeout=10)
216
+ assert web_client.get_text("#dynamic-content") == "Loaded Content"
217
+ ```
218
+
219
+ ## Examples
220
+
221
+ See the test files for comprehensive examples:
222
+ - `tests/test_jsonvalidator.py` - JSON validation examples covering basic validation, type checking, nested objects, constraints, and error handling
223
+ - `tests/test_restapiclient.py` - REST API client examples with testcontainers integration
224
+ - `tests/test_playwrightclient.py` - Playwright web client examples for browser automation with testcontainers
225
+
226
+ ## Best Practices
227
+
228
+ ### Use Testcontainers for Isolated Environments
229
+
230
+ When testing web applications, it's recommended to use testcontainers to create isolated environments for your services.
231
+ This ensures that your tests are reproducible and do not interfere with each other.
232
+
233
+ ## License
234
+
235
+ MIT
@@ -0,0 +1,212 @@
1
+ # Klab Pytest Toolkit - Web Fixtures
2
+
3
+ Custom pytest fixtures for web testing.
4
+ The goal is to allow testers to easily test web applications (html/json/rest api) with reusable components.
5
+
6
+ At the moment the package provides the following fixtures:
7
+
8
+ - `response_validator_factory`: Factory for create JSON response validator instances with custom configurations.
9
+ - `api_client_factory`: Factory for create different API client instances.
10
+ - REST API client for making HTTP requests to RESTful services.
11
+ - `web_client_factory`: Factory to create web client instances for browser automation
12
+ - Playwright-based web client for end-to-end testing of web applications.
13
+
14
+ ## Installation
15
+
16
+ ```bash
17
+ pip install klab-pytest-toolkit-web
18
+ ```
19
+
20
+ ## Usage
21
+
22
+ ### JSON Response Validator
23
+
24
+ **Create the fixture**
25
+
26
+ The factory class `ResponseValidatorFactory` is already provided as a pytest fixture `response_validator_factory`.
27
+
28
+ ```python
29
+ @pytest.fixture
30
+ def json_validator_user_schema(response_validator_factory) -> JsonResponseValidator:
31
+ """Fixture to provide a JSON response validator for user schema."""
32
+ user_schema = {
33
+ "type": "object",
34
+ "properties": {
35
+ "id": {"type": "integer"},
36
+ "name": {"type": "string"},
37
+ },
38
+ "required": ["id", "name"]
39
+ }
40
+ return response_validator_factory.create_json_validator(schema=user_schema)
41
+ ```
42
+
43
+ **Functions**
44
+
45
+ The validator contains one main function to validate a response against the schema. Below is an example of how to use the validator in a test.
46
+
47
+ ```python
48
+ def test_user_api(json_validator_user_schema):
49
+ """Test user API response validation."""
50
+ response_data = {
51
+ "id": 1,
52
+ "name": "John Doe"
53
+ }
54
+ assert json_validator_user_schema.validate_response(response_data)
55
+ ```
56
+
57
+ ### REST API Client
58
+
59
+ **Create the fixture**
60
+
61
+ The factory class `ApiClientFactory` is already provided as a pytest fixture `api_client_factory`.
62
+ To pass the url or other header information, you can pass this as environment variables or configure directly in the fixture.
63
+ Below is an example of creating a REST API client fixture from a testcontainer url.
64
+
65
+ ```python
66
+
67
+ @pytest.fixture(scope="session")
68
+ def httpbin_container():
69
+ """Fixture to provide an HTTPBin container for testing."""
70
+
71
+ with DockerContainer("kennethreitz/httpbin:latest") as httpbin:
72
+ httpbin.with_exposed_ports(80)
73
+ httpbin.waiting_for(HttpWaitStrategy(path="/get", port=80).for_status_code(200))
74
+ httpbin.start()
75
+ port = httpbin.get_exposed_port(80)
76
+ base_url = f"http://localhost:{port}"
77
+ yield base_url
78
+
79
+ @pytest.fixture
80
+ def rest_api_client(api_client_factory, httpbin_container) -> RestApiClient:
81
+ """Fixture to provide a REST API client."""
82
+ return api_client_factory.create_rest_client(base_url=httpbin_container)
83
+ ```
84
+
85
+ **Functions**
86
+
87
+ The REST API client provides functions to make HTTP requests. These are some examples:
88
+
89
+ ```python
90
+ def test_get_request(rest_api_client: RestApiClient):
91
+ """Test basic GET request with query parameters."""
92
+ response = rest_api_client.get("/get", params={"test": "value"})
93
+
94
+ assert response.status_code == 200
95
+ json_data = response.json()
96
+ assert json_data["args"]["test"] == "value"
97
+
98
+ def test_post_request(rest_api_client: RestApiClient):
99
+ """Test basic POST request with JSON body."""
100
+ response = rest_api_client.post("/post", payload={"key": "value"})
101
+
102
+ assert response.status_code == 200
103
+ json_data = response.json()
104
+ assert json_data["json"]["key"] == "value"
105
+
106
+ def test_update_request(rest_api_client: RestApiClient):
107
+ """Test basic PUT request with JSON body."""
108
+ response = rest_api_client.put("/put", payload={"update": "data"})
109
+
110
+ assert response.status_code == 200
111
+ json_data = response.json()
112
+ assert json_data["json"]["update"] == "data"
113
+
114
+ def test_delete_request(rest_api_client: RestApiClient):
115
+ """Test basic DELETE request."""
116
+ response = rest_api_client.delete("/delete")
117
+
118
+ assert response.status_code == 200
119
+ json_data = response.json()
120
+ assert json_data["url"].endswith("/delete")
121
+ ```
122
+
123
+ ### gRPC Client
124
+
125
+ **Create the fixture**
126
+
127
+ The factory class `ApiClientFactory` is already provided as a pytest fixture `api_client_factory`.
128
+ You can create a gRPC client fixture as shown below:
129
+
130
+ ```python
131
+ @pytest.fixture
132
+ def grpc_client(api_client_factory) -> GrpcClient:
133
+ """Fixture to provide a gRPC client."""
134
+ return api_client_factory.create_grpc_client(
135
+ target="localhost:50051",
136
+ proto_file="path/to/your/service.proto"
137
+ )
138
+ ```
139
+
140
+ **Functions**
141
+
142
+ The `GrpcClient` provides gRPC call functionality by dynamically invoking methods defined in the provided proto file. It is imported the that the proto file defines a service with methods like `GetUser`. You will not get any code completion in your IDE since the methods are dynamically resolved at runtime, but you get error handling if the method does not exist.
143
+
144
+ ```python
145
+ def test_grpc_get_user(grpc_client: GrpcClient):
146
+ """Test gRPC GetUser call."""
147
+ response = grpc_client.GetUser(id=123)
148
+
149
+ assert response.id == 123
150
+ assert response.name == "John Doe"
151
+ ```
152
+
153
+ ### Playwright Web Client
154
+
155
+ **Create the fixture**
156
+
157
+ The factory class `WebClientFactory` is already provided as a pytest fixture `web_client_factory`.
158
+ For playwright, you might install the browsers first by running `playwright install` in your environment.
159
+ You can create a Playwright web client fixture as shown below:
160
+
161
+ ```python
162
+ @pytest.fixture
163
+ def web_client(web_client_factory) -> PlaywrightWebClient:
164
+ """Fixture to provide a Playwright web client."""
165
+ with web_client_factory.create_client(client_type="playwright", headless=True) as client:
166
+ yield client
167
+ ```
168
+
169
+ **Functions**
170
+
171
+ The `WebClient` provides a variety of functions for browser automation. Refer to the api of the instance.
172
+ Here are some examples of common operations:
173
+
174
+ ```python
175
+ def test_navigate_and_click(web_client):
176
+ """Test navigation and clicking a button."""
177
+ web_client.navigate_to("https://example.com")
178
+ web_client.click("#start-button")
179
+ assert web_client.get_text("#result") == "Started"
180
+
181
+ def test_form_submission(web_client):
182
+ """Test form submission."""
183
+ web_client.navigate_to("https://example.com/form")
184
+ web_client.fill_input("#name", "Test User")
185
+ web_client.fill_input("#email", "max@muster.com")
186
+ web_client.click("#submit-button")
187
+ assert web_client.get_text("#confirmation") == "Thank you for your submission!"
188
+
189
+ def test_wait_for_element(web_client):
190
+ """Test waiting for an element to appear."""
191
+ web_client.navigate_to("https://example.com/dynamic")
192
+ web_client.wait_for_element("#dynamic-content", timeout=10)
193
+ assert web_client.get_text("#dynamic-content") == "Loaded Content"
194
+ ```
195
+
196
+ ## Examples
197
+
198
+ See the test files for comprehensive examples:
199
+ - `tests/test_jsonvalidator.py` - JSON validation examples covering basic validation, type checking, nested objects, constraints, and error handling
200
+ - `tests/test_restapiclient.py` - REST API client examples with testcontainers integration
201
+ - `tests/test_playwrightclient.py` - Playwright web client examples for browser automation with testcontainers
202
+
203
+ ## Best Practices
204
+
205
+ ### Use Testcontainers for Isolated Environments
206
+
207
+ When testing web applications, it's recommended to use testcontainers to create isolated environments for your services.
208
+ This ensures that your tests are reproducible and do not interfere with each other.
209
+
210
+ ## License
211
+
212
+ MIT
@@ -0,0 +1,58 @@
1
+ [build-system]
2
+ requires = ["hatchling"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "klab-pytest-toolkit-web"
7
+ dynamic = ["version"]
8
+ description = "Pytest web fixtures for the Klab Pytest Toolkit"
9
+ authors = [{ name = "Burak Kizilkaya", email = "burak.kizilkaya@outlook.com" }]
10
+ requires-python = ">=3.11,<4"
11
+ readme = "README.md"
12
+ license = "MIT"
13
+ classifiers = [
14
+ "Development Status :: 3 - Alpha",
15
+ "Intended Audience :: Developers",
16
+ "License :: OSI Approved :: MIT License",
17
+ "Programming Language :: Python :: 3",
18
+ ]
19
+ dependencies = [
20
+ "jsonschema>=4.25.1",
21
+ "pytest>=8.3.5",
22
+ "playwright>=1.57.0",
23
+ "requests>=2.32.5",
24
+ "grpcio>=1.66.0",
25
+ "grpcio-tools>=1.66.0",
26
+ "grpcio-reflection>=1.66.0",
27
+ ]
28
+
29
+ [project.urls]
30
+ Changelog = "https://github.com/klab365/klab-pytest-toolkit/blob/main/CHANGELOG.md"
31
+ Repository = "https://github.com/klab365/klab-pytest-toolkit"
32
+ Issues = "https://github.com/klab365/klab-pytest-toolkit/issues"
33
+
34
+ [project.entry-points.pytest11]
35
+ klab_pytest_toolkit_web = "klab_pytest_toolkit_web.plugin"
36
+
37
+ [tool.hatch.version]
38
+ path = "src/klab_pytest_toolkit_web/__init__.py"
39
+
40
+ [tool.hatch.build.targets.sdist]
41
+ exclude = [
42
+ "tests",
43
+ ]
44
+
45
+ [tool.pytest.ini_options]
46
+ asyncio_mode = "auto"
47
+ asyncio_default_fixture_loop_scope = "function"
48
+ pythonpath = [
49
+ "."
50
+ ]
51
+ filterwarnings = [
52
+ "ignore::DeprecationWarning:testcontainers.core.waiting_utils",
53
+ ]
54
+
55
+ [dependency-groups]
56
+ dev = [
57
+ "testcontainers>=4.13.3",
58
+ ]