summaryrefslogtreecommitdiffstats
path: root/testing/webcompat/interventions/tests/test_1570108_steamcommunity.py
blob: bef7efd9d5256887b259cfb0936aae4f85975af4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
import pytest

URL = "https://steamcommunity.com/chat"


USERID_CSS = "input[type='text'][class*='newlogindialog']"
PASSWORD_CSS = "input[type='password'][class*='newlogindialog']"
SIGNIN_CSS = "button[type='submit'][class*='newlogindialog']"
GEAR_CSS = ".friendListButton"
LOGIN_FAIL_XPATH = (
    "//*[contains(text(), 'try again') and " "contains(@class, 'FormError')]"
)
AUTH_CSS = "[class*='newlogindialog_ProtectingAccount']"
AUTH_DIGITS_CSS = "[class*='newlogindialog_SegmentedCharacterInput'] input[type='text']"
AUTH_RETRY_CSS = "[class*='newlogindialog_TryAgainButton']"
AUTH_RETRY_LOADER_CSS = "[class*='newlogindialog_Loading']"
RATE_TEXT = "too many login failures"
VOICE_XPATH = (
    "//*[contains(text(), 'Voice') and "
    "contains(@class, 'pagedsettings_PagedSettingsDialog_PageListItem')]"
)
MIC_BUTTON_CSS = "button.LocalMicTestButton"
UNSUPPORTED_TEXT = "currently unsupported in Firefox"


async def do_2fa(client):
    digits = client.find_css(AUTH_DIGITS_CSS, all=True)
    assert len(digits) > 0

    loader = client.css(AUTH_RETRY_LOADER_CSS)
    if client.find_element(loader):
        client.await_element_hidden(loader)
    for digit in digits:
        if digit.property("value"):
            digit.send_keys(u"\ue003")  # backspace

    code = input("**** Enter two-factor authentication code: ")
    for i, digit in enumerate(code):
        if len(digits) > i:
            digits[i].send_keys(digit)

    client.await_element(loader, timeout=10)
    client.await_element_hidden(loader)


async def load_mic_test(client, credentials, should_do_2fa):
    await client.navigate(URL)

    async def login():
        userid = client.await_css(USERID_CSS)
        password = client.find_css(PASSWORD_CSS)
        submit = client.find_css(SIGNIN_CSS)
        assert client.is_displayed(userid)
        assert client.is_displayed(password)
        assert client.is_displayed(submit)

        userid.send_keys(credentials["username"])
        password.send_keys(credentials["password"])
        submit.click()

    await login()

    while True:
        auth, retry, gear, fail, rate = client.await_first_element_of(
            [
                client.css(AUTH_CSS),
                client.css(AUTH_RETRY_CSS),
                client.css(GEAR_CSS),
                client.xpath(LOGIN_FAIL_XPATH),
                client.text(RATE_TEXT),
            ],
            is_displayed=True,
            timeout=20,
        )

        if retry:
            await do_2fa(client)
            continue

        if rate:
            pytest.skip(
                "Too many Steam login attempts in a short time; try again later."
            )
            return None
        elif auth:
            if should_do_2fa:
                await do_2fa(client)
                continue

            pytest.skip(
                "Two-factor authentication requested; disable Steam Guard"
                " or run this test with --do-2fa to live-input codes"
            )
            return None
        elif fail:
            pytest.skip("Invalid login provided.")
            return None
        else:
            break

    assert gear
    gear.click()

    voice = client.await_xpath(VOICE_XPATH, is_displayed=True)
    voice.click()

    mic_test = client.await_css(MIC_BUTTON_CSS, is_displayed=True)
    return mic_test


@pytest.mark.skip_platforms("android")
@pytest.mark.asyncio
@pytest.mark.with_interventions
async def test_enabled(client, credentials, should_do_2fa):
    mic_test = await load_mic_test(client, credentials, should_do_2fa)
    if not mic_test:
        return

    with client.assert_getUserMedia_called():
        mic_test.click()

    assert not client.find_text(UNSUPPORTED_TEXT)


@pytest.mark.skip_platforms("android")
@pytest.mark.asyncio
@pytest.mark.without_interventions
async def test_disabled(client, credentials, should_do_2fa):
    mic_test = await load_mic_test(client, credentials, should_do_2fa)
    if not mic_test:
        return

    mic_test.click()

    unsupported = client.await_text(UNSUPPORTED_TEXT)
    assert client.is_displayed(unsupported)