16
16
import shutil
17
17
import os
18
18
import sys
19
+
20
+ import traceback
21
+
19
22
import warnings
20
23
from typing import Any , Callable , Dict , Generator , List , Optional
21
- import logging
24
+
22
25
import pytest
23
26
from playwright .sync_api import (
24
27
Browser ,
33
36
import tempfile
34
37
35
38
36
- log = logging .getLogger (__name__ )
37
-
38
39
artifacts_folder = tempfile .TemporaryDirectory (prefix = "playwright-pytest-" )
39
40
40
41
@@ -76,34 +77,6 @@ def pytest_configure(config: Any) -> None:
76
77
"markers" ,
77
78
"browser_context_args(**kwargs): provide additional arguments to browser.new_context()" ,
78
79
)
79
- log .debug ("pytest_configure" )
80
- class Teardown :
81
- failed = False
82
- setattr (config , "teardown" , Teardown )
83
-
84
-
85
- def pytest_runtest_teardown (item ):
86
- # import faulthandler
87
- # faulthandler.dump_traceback(all_threads=True)
88
- log .debug ("pytest_runtest_teardown" )
89
- item .config .teardown .failed = True
90
-
91
-
92
- def pytest_sessionfinish (session , exitstatus ):
93
- log .debug ("pytest_runtest_teardown" )
94
- log .debug (f"{ exitstatus = } " )
95
-
96
-
97
- def pytest_exception_interact (node , call , report ):
98
- log .debug ("1pytest_exception_interact" )
99
- log .debug (f"{ node .config .teardown .failed = } " )
100
- log .debug (f"{ node .session .testsfailed = } " )
101
- excinfo = call .exc_info if hasattr (call , "exc_info" ) else None
102
- log .debug (f"{ excinfo = } " )
103
-
104
- if call .when == "teardown" :
105
- log .debug ("2pytest_exception_interact" )
106
- node .config .teardown .failed = True
107
80
108
81
109
82
# Making test result information available in fixtures
@@ -286,52 +259,33 @@ def context(
286
259
)
287
260
288
261
yield context
289
- # import traceback
290
- # log.debug(f"{dir(traceback)=}")
291
- # log.debug(f"{traceback.print_last()=}")
292
- # stack = traceback.extract_stack()
293
- # log.debug(f"{stack=}")
294
- # for frame_summary in stack:
295
- # log.debug(f"{frame_summary.filename=}")
296
- # log.debug(f"{frame_summary.name=}")
297
- # log.debug(f"{frame_summary.colno=}")
298
-
299
-
300
- # log.debug(f"{traceback.print_stack()=}")
301
-
302
- # log.debug(f"{traceback.print_exc()=}")
303
-
304
- log .debug (f"{ request .session .testscollected = } " )
305
- log .debug (f"{ request .session .exitstatus = } " )
306
- log .debug (f"{ request .session .testsfailed = } " )
307
-
308
- if request .session .testsfailed :
309
- log .debug ("Only print if failed" )
310
-
311
- log .debug ("context" )
312
262
# If request.node is missing rep_call, then some error happened during execution
313
263
# that prevented teardown, but should still be counted as a failure
314
- failed_setup = request .node .rep_setup .failed if hasattr (request .node , "rep_setup" ) else False
315
- failed_call = request .node .rep_call .failed if hasattr (request .node , "rep_call" ) else False
316
- failed_teardown = request .node .rep_teardown .failed if hasattr (request .node , "rep_teardown" ) else False
317
-
318
- failed_xteardown = request .config .teardown .failed if hasattr (request .config , "teardown" ) else False
319
-
320
-
321
- failed = failed_setup or failed_call or failed_xteardown
322
- log .debug (f"{ failed = } " )
323
- log .debug (f"{ failed_setup = } " )
324
- log .debug (f"{ failed_call = } " )
325
- log .debug (f"{ failed_teardown = } " )
326
- log .debug (f"{ failed_xteardown = } " )
264
+ failed_setup = (
265
+ request .node .rep_setup .failed if hasattr (request .node , "rep_setup" ) else False
266
+ )
267
+ failed_call = (
268
+ request .node .rep_call .failed if hasattr (request .node , "rep_call" ) else False
269
+ )
327
270
271
+ passed_setup = (
272
+ request .node .rep_setup .passed if hasattr (request .node , "rep_setup" ) else False
273
+ )
274
+ passed_call = (
275
+ request .node .rep_call .passed if hasattr (request .node , "rep_call" ) else False
276
+ )
328
277
329
- log .debug (f"{ hasattr (request .node , 'rep_setup' )= } " )
330
- log .debug (f"{ hasattr (request .node , 'rep_call' )= } " )
331
- log .debug (f"{ hasattr (request .node , 'rep_teardown' )= } " )
278
+ failed_xteardown = False
332
279
333
- log .debug (f"{ hasattr (request .config , 'teardown' )= } " )
280
+ if (passed_setup or passed_call ) and not (failed_setup or failed_call ):
281
+ # check tb under stack if any other teardown was failed, False by default
282
+ # looks like workaround for https://github.com/pytest-dev/pytest/issues/9909
283
+ for trace , _ in traceback .walk_stack (None ):
284
+ if trace .f_locals .get ("these_exceptions" ):
285
+ failed_xteardown = True
286
+ break
334
287
288
+ failed = failed_setup or failed_call or failed_xteardown
335
289
336
290
if capture_trace :
337
291
retain_trace = tracing_option == "on" or (
@@ -344,11 +298,9 @@ def context(
344
298
context .tracing .stop ()
345
299
346
300
screenshot_option = pytestconfig .getoption ("--screenshot" )
347
- log .debug (f"{ screenshot_option = } " )
348
301
capture_screenshot = screenshot_option == "on" or (
349
302
failed and screenshot_option == "only-on-failure"
350
303
)
351
- log .debug (f"{ capture_screenshot = } " )
352
304
if capture_screenshot :
353
305
for index , page in enumerate (pages ):
354
306
human_readable_status = "failed" if failed else "finished"
0 commit comments