33import os
44import re
55import subprocess
6- import tempfile
6+ import typing
77from collections import namedtuple
88
9+ from playwright .path_utils import get_file_dirname
10+
11+ _dirname = get_file_dirname ()
12+
913TestCase = namedtuple ("TestCase" , ["api" , "file" , "test" ])
1014
1115
12- def pytest_test_cases ():
16+ def pytest_test_cases () -> typing . Generator [ TestCase , None , None ] :
1317 p = subprocess .run (
1418 ["pytest" , "--browser" , "chromium" , "--collect-only" , "-q" ],
19+ cwd = _dirname / ".." / "tests" ,
1520 stdout = subprocess .PIPE ,
21+ check = True ,
1622 )
1723 regex = (
1824 r"tests/(?P<api>a?sync)/test_(?P<file>.*)\.py::test_(?P<test>.*)\[chromium\]"
@@ -24,32 +30,44 @@ def pytest_test_cases():
2430 )
2531
2632
27- def jest_test_cases (playwright_js_path ):
28- env = os .environ .copy ()
29- env ["REPORT_ONLY" ] = "true"
30- with tempfile .NamedTemporaryFile () as results :
31- subprocess .run (
32- ["npx" , "jest" , "--json" , "--outputFile" , results .name ],
33- env = env ,
34- cwd = playwright_js_path ,
35- stderr = subprocess .DEVNULL ,
36- )
33+ def jest_test_cases (playwright_js_path : str ) -> typing .Generator [TestCase , None , None ]:
34+ p = subprocess .run (
35+ [
36+ "node" ,
37+ os .path .join ("test" , "runner" ),
38+ "test" ,
39+ "--trial-run" ,
40+ "--reporter" ,
41+ "json" ,
42+ ],
43+ cwd = playwright_js_path ,
44+ stdout = subprocess .PIPE ,
45+ stderr = subprocess .DEVNULL ,
46+ check = True ,
47+ )
48+
49+ tests = json .loads (p .stdout .decode ())
50+ for test in [* tests ["pending" ], * tests ["passes" ], * tests ["failures" ]]:
51+ regex = r"(.*/)?(?P<file>[^/]+)\.spec\.[jt]s$"
52+
53+ match = re .match (regex , test ["file" ])
54+ if not match :
55+ continue
56+
57+ file = match .group ("file" )
3758
38- for test_suite in json .load (results )["testResults" ]:
39- regex = r"(.*/)?(?P<file>[^/]+)\.spec\.[jt]s$"
40- file = re .match (regex , test_suite ["name" ]).group ("file" )
41- for assertion in test_suite ["assertionResults" ]:
42- yield TestCase ("sync" , normalized (file ), normalized (assertion ["title" ]))
43- yield TestCase (
44- "async" , normalized (file ), normalized (assertion ["title" ])
45- )
59+ yield TestCase ("sync" , normalized (file ), normalized (test ["title" ]))
60+ yield TestCase ("async" , normalized (file ), normalized (test ["title" ]))
4661
4762
48- def normalized (original ):
49- return re .sub (r"[^a-z_]" , "_" , original , flags = re .IGNORECASE )
63+ def normalized (original : str ) -> str :
64+ cleaned = re .sub (r"[^a-z0-9_]" , "_" , original , flags = re .IGNORECASE )
65+ cleaned = re .sub (r"[_]+" , "_" , cleaned )
66+ cleaned = cleaned .strip ("_" )
67+ return cleaned
5068
5169
52- def main ():
70+ def main () -> None :
5371 parser = argparse .ArgumentParser ()
5472 parser .add_argument (
5573 "--playwright-js-path" ,
@@ -69,12 +87,13 @@ def main():
6987 javascript_tests = set (jest_test_cases (args .playwright_js_path ))
7088
7189 if args .api :
72- javascript_tests = set ([x for x in javascript_tests if x [ 0 ] == args .api ])
90+ javascript_tests = set ([x for x in javascript_tests if x . api == args .api ])
7391
7492 missing = javascript_tests .difference (python_tests )
7593 found = javascript_tests .intersection (python_tests )
7694
7795 print ("MISSING, MISPELLED, OR MISNAMED:" )
96+ print ("=" * 80 )
7897 for (api , file , test ) in sorted (missing ):
7998 print (f"{ api } /test_{ file } .py::test_{ test } " )
8099
0 commit comments