up
This commit is contained in:
@@ -98,6 +98,65 @@ def check_browser_flow(stand, fixtures):
|
||||
click('Вход')
|
||||
wait("location.pathname==='/office'", 'login')
|
||||
|
||||
def check_presence(data):
|
||||
from flow import run, wait_for
|
||||
api = stand.apis['venue']
|
||||
device_id = js("return localStorage.getItem('evening-detective-device-ID')")
|
||||
assert device_id
|
||||
|
||||
def connections():
|
||||
devices = api.request('/api/devices')['devices']
|
||||
return next((d['connections'] for d in devices if d['ID'] == device_id), [])
|
||||
|
||||
def has_kind(kind):
|
||||
return any(c['kind'] == kind for c in connections())
|
||||
|
||||
wait_for(lambda: has_kind('organizer'), 'organizer presence')
|
||||
organizer_window = command('WebDriver:GetWindowHandle')
|
||||
if isinstance(organizer_window, dict):
|
||||
organizer_window = organizer_window['value']
|
||||
team_window = command('WebDriver:NewWindow', {'type': 'tab'})['handle']
|
||||
command('WebDriver:SwitchToWindow', {'handle': team_window})
|
||||
captain = data['teams'][0]
|
||||
navigate(f'/team-story/{captain["ID"]}?password={urllib.parse.quote(captain["password"])}')
|
||||
wait_for(lambda: has_kind('team'), 'player presence')
|
||||
screen_window = command('WebDriver:NewWindow', {'type': 'tab'})['handle']
|
||||
command('WebDriver:SwitchToWindow', {'handle': screen_window})
|
||||
navigate('/screen')
|
||||
wait_for(lambda: has_kind('screen'), 'screen presence')
|
||||
screen_connection = next(c for c in connections() if c['kind'] == 'screen')
|
||||
# Bind the actual browser session, whose credentials stay inside the browser.
|
||||
saved = js("return JSON.parse(sessionStorage.getItem('evening-detective-screen-session'))")
|
||||
assert saved['screenID'] == str(screen_connection['screenID'])
|
||||
api.request(f'/api/screens/{saved["screenID"]}/bind', {**saved, 'gameID': data['game']})
|
||||
js("window.dispatchEvent(new Event('online'));return true;")
|
||||
wait_for(lambda: any(c['ID'] == screen_connection['ID'] and c.get('gameID') == data['game'] for c in connections()), 'bound screen presence')
|
||||
assert {c['kind'] for c in connections()} >= {'organizer', 'team', 'screen'}
|
||||
command('WebDriver:CloseWindow')
|
||||
command('WebDriver:SwitchToWindow', {'handle': team_window})
|
||||
command('WebDriver:CloseWindow')
|
||||
command('WebDriver:SwitchToWindow', {'handle': organizer_window})
|
||||
old_id = next(c['ID'] for c in connections() if c['kind'] == 'organizer')
|
||||
click('Главная')
|
||||
wait("location.pathname==='/'", 'SPA navigation')
|
||||
wait_for(lambda: any(c['ID'] == old_id and c['kind'] == 'browser' for c in connections()), 'SPA clears context on same connection')
|
||||
# Drop only heartbeat requests; gameplay and authorization remain live.
|
||||
js("window.presenceFetch=window.fetch;window.fetch=(url,options)=>String(url).includes('/devices/heartbeat')?Promise.reject(new Error('test offline')):window.presenceFetch(url,options);return true;")
|
||||
before = next(c['lastSeenAt'] for c in connections() if c['ID'] == old_id)
|
||||
time.sleep(22)
|
||||
assert next(c['lastSeenAt'] for c in connections() if c['ID'] == old_id) == before
|
||||
js("window.fetch=window.presenceFetch;window.dispatchEvent(new Event('online'));return true;")
|
||||
wait_for(lambda: next(c['lastSeenAt'] for c in connections() if c['ID'] == old_id) != before, 'network recovery')
|
||||
run('docker', 'stop', stand.name + '-venue-app')
|
||||
run('docker', 'start', stand.name + '-venue-app')
|
||||
wait_for(lambda: api.request('/api/test/ping') == {}, 'browser backend restart')
|
||||
wait_for(lambda: any(c['ID'] == old_id for c in connections()), 'automatic interval re-registration', 30)
|
||||
navigate(f'/games/{data["game"]}')
|
||||
wait_for(lambda: has_kind('organizer'), 'reloaded organizer presence')
|
||||
new_id = next(c['ID'] for c in connections() if c['kind'] == 'organizer')
|
||||
assert new_id != old_id and js("return localStorage.getItem('evening-detective-device-ID')") == device_id
|
||||
print('PASS: stage 12 real Firefox organizer/player/screen, grouped tabs, SPA context clearing, reload UUID, stopped heartbeat/network recovery and interval re-registration after restart', flush=True)
|
||||
|
||||
command('WebDriver:NewSession', {'capabilities': {'alwaysMatch': {'acceptInsecureCerts': True}}})
|
||||
for width, data in zip((1440, 390), fixtures, strict=True):
|
||||
game, captain = data['game'], data['teams'][0]
|
||||
@@ -132,6 +191,8 @@ def check_browser_flow(stand, fixtures):
|
||||
assert js("return document.querySelector('[role=dialog]').contains(document.activeElement)"), 'Modal lost keyboard focus'
|
||||
click('Открыть игру')
|
||||
wait(f"location.pathname==='/games/{game}'", 'open imported game')
|
||||
if width == 1440:
|
||||
check_presence(data)
|
||||
navigate(f'/games/{game}?tab=payment')
|
||||
wait("document.body.innerText.includes('Проверить билет')", 'ticket checking')
|
||||
click('Проверить билет')
|
||||
|
||||
Reference in New Issue
Block a user