1+ import re
12import time
3+ from typing import Any , cast
24
35from playwright .sync_api import expect , sync_playwright
46
@@ -12,7 +14,7 @@ def setup_all(cls):
1214 cls .context = cls .browser .new_context ()
1315 cls .context .tracing .start (screenshots = True , snapshots = True , sources = True )
1416
15- expect .set_options (timeout = 2 )
17+ expect .set_options (timeout = 200 )
1618
1719
1820def teardown_all (cls ):
@@ -21,7 +23,35 @@ def teardown_all(cls):
2123 cls .playwright .stop ()
2224
2325
26+ def drag_slider (page , offset_px = 80 ):
27+ """Drag the slider handle by offset_px (positive = right, negative = left)."""
28+ slider = page .get_by_role ("slider" )
29+ box = slider .bounding_box ()
30+ assert box , "Slider handle should have bounding box"
31+ center_x = box ["x" ] + box ["width" ] / 2
32+ center_y = box ["y" ] + box ["height" ] / 2
33+ page .mouse .move (center_x , center_y )
34+ page .mouse .down ()
35+ page .mouse .move (center_x + offset_px , center_y )
36+ page .mouse .up ()
37+ time .sleep (0.3 )
38+
39+
40+ def login (page , base_url = "http://localhost:3000/" ):
41+ """Log in with username_1 / Test1234 on the given page."""
42+ page .goto (base_url )
43+ page .get_by_role ("button" , name = "Log in" ).click ()
44+ page .get_by_placeholder ("username or email" ).fill ("username_1" )
45+ page .get_by_placeholder ("password" ).fill ("Test1234" )
46+ page .get_by_role ("button" , name = "Log in" , exact = True ).last .click ()
47+ time .sleep (1 )
48+
49+
2450class TestSimpleFunctionality :
51+ playwright = None
52+ browser = None
53+ context = None
54+
2555 @classmethod
2656 def setup_class (cls ):
2757 setup_all (cls )
@@ -30,23 +60,68 @@ def setup_class(cls):
3060 def teardown_class (cls ):
3161 teardown_all (cls )
3262
63+ def teardown_method (self , method ):
64+ context = cast (Any , self .__class__ .context )
65+ if context is not None :
66+ for page in context .pages :
67+ page .close ()
68+ context .clear_cookies ()
69+
3370 @classmethod
3471 def test_login (cls ):
35- context = cls .context
72+ context = cast (Any , cls .context )
73+ assert context is not None
3674 page = context .new_page ()
3775 page .on ("console" , lambda msg : print ("[Browser console] " , msg .text ))
3876
39- url = "http://localhost:3000/"
40- page .goto (url )
77+ login (page )
78+
79+ page .get_by_role ("banner" ).get_by_role ("link" , name = "Questions" ).click ()
80+ page .get_by_role ("button" , name = "Filter" ).click ()
81+ page .get_by_role ("button" , name = "Binary" ).click ()
82+ page .get_by_role ("button" , name = "Open" ).click ()
83+ page .get_by_role ("button" , name = "Done" ).click ()
4184
42- page .get_by_role ("button" , name = "Log in" ).click ()
85+ @classmethod
86+ def test_create_binary_forecast_via_ui (cls ):
87+ context = cast (Any , cls .context )
88+ assert context is not None
4389
44- page . get_by_placeholder ( "username or email" ). fill ( "username_1" )
45- page .get_by_placeholder ( "password" ). fill ( "Test1234" )
46- page . get_by_role ( "button" , name = "Log in" , exact = True ). last . click ()
47- time . sleep ( 1 )
90+ page = context . new_page ( )
91+ page .on ( "console" , lambda msg : print ( "[Browser console] " , msg . text ) )
92+
93+ login ( page )
4894 page .get_by_role ("banner" ).get_by_role ("link" , name = "Questions" ).click ()
4995 page .get_by_role ("button" , name = "Filter" ).click ()
5096 page .get_by_role ("button" , name = "Binary" ).click ()
5197 page .get_by_role ("button" , name = "Open" ).click ()
98+ time .sleep (1 )
5299 page .get_by_role ("button" , name = "Done" ).click ()
100+ time .sleep (1 )
101+ links = page .locator ("a[href^='/questions/']" )
102+ for i in range (links .count ()):
103+ href = links .nth (i ).get_attribute ("href" ) or ""
104+ if re .match (r"/questions/\d+/" , href ):
105+ links .nth (i ).click ()
106+ break
107+
108+ time .sleep (1 )
109+
110+ drag_slider (page , offset_px = 80 )
111+
112+ slider = page .get_by_role ("slider" )
113+ value_div = slider .locator ("div" )
114+ predicted_value = value_div .inner_text ()
115+
116+ predict_button = page .get_by_role (
117+ "button" , name = re .compile (r"(Predict|Save changes|Reaffirm)" , re .IGNORECASE )
118+ ).first
119+ predict_button .click ()
120+
121+ time .sleep (1 )
122+ page .reload ()
123+ time .sleep (1 )
124+
125+ slider_after = page .get_by_role ("slider" )
126+ value_div_after = slider_after .locator ("div" )
127+ expect (value_div_after ).to_have_text (predicted_value )
0 commit comments