from random import choice, shuffle from playwright.sync_api import Playwright, sync_playwright, expect, Page from playwright_stealth import stealth_sync from logging import * from re import findall, search from actions.checks import check_logged_in def play(page: Page): check_logged_in(page) quiz_type = detect_quiz_type(page) match quiz_type: case 8 | 9: info('Detected quiz_8.') play_quiz_8(page) case 5 | 4: info('Detected quiz_4.') play_quiz_4(page) case 3 | 2: info('Detected quiz_2.') play_quiz_2(page) case 1: info('Detected poll.') play_poll(page) case 0: info('Detected empty page.') def detect_quiz_type(page: Page) -> int: info("Detecting quiz type.") if "bt_PollRadio" in page.content(): return 1 else: try: # RGPD selector = page.locator("#rqStartQuiz") expect(selector).to_be_visible(timeout=10_000) selector.click() return page.content().count("rqAnswerOption") - 1 except AssertionError as e: if "rqQuestionState" in page.content(): # The quiz is already started warning("Detected via recovery mode.") return page.content().count("rqAnswerOption") - 1 return 0 def play_quiz_8(page: Page): info("Playing quiz 8.") num_question = len(findall("", page.content())) + 1 info(f"Looping on {num_question} questions.") counter = 0 # rgpd_popup(driver) for _ in range(num_question): correct_answers = [] for i in range(1, 9): element = page.locator(f'#rqAnswerOption{i - 1}') # todo can probably be optimised using filter and has_text if 'iscorrectoption="True"' in element.evaluate("el => el.outerHTML"): correct_answers.append(f'#rqAnswerOption{i - 1}') shuffle(correct_answers) for answer_id in correct_answers: page.locator(answer_id).click() page.wait_for_timeout(1000) page.wait_for_timeout(3000) # todo check if there is a better method than hardcoded timout page.wait_for_timeout(3000) # todo check if there is a better method than hardcoded timout def play_quiz_4(page: Page): info("Playing quiz 4.") num_question = len(findall("", page.content())) + 1 info(f"Looping on {num_question} questions.") for i in range(num_question): txt = page.content() answer_option = search('correctAnswer":"([^"]+)', txt)[1] answer_option = answer_option.replace("\\u0027", "'") # replace Unicode weird symbols page.locator(f'css=[data-option="{answer_option}"]').click() info(f'Validated answer n°{i + 1}.') page.wait_for_load_state('load') debug(f'Next page loaded.') info("Quiz 4 successful.") def play_quiz_2(page: Page): info("Playing quiz 2.") for j in range(10): # todo de-hardcode the value js_function = """ function get_correct_answer(){ function br(n) { for (var r, t = 0, i = 0; i < n.length; i++)t += n.charCodeAt(i); return r = parseInt(_G.IG.substr(_G.IG.length - 2), 16), t += r, t.toString() } // Ms check function function namedRAValue() { //allow calls to getRAvalue return _w.getRAValue() }; if (br(document.getElementById("rqAnswerOption0").attributes["data-option"].value) == namedRAValue()){ return(0); } else { return(1); } }; return(get_correct_answer()) """ correct_answer_value = page.evaluate(js_function) page.locator(f"#rqAnswerOption{correct_answer_value}").click() page.wait_for_timeout(2000) info("Quiz 2 successful.") page.wait_for_timeout(3000) # todo check if there is a better method than hardcoded timout def play_poll(page: Page): info("Playing poll.") answer_elem = page.locator(f"#btoption{choice([0, 1])}") answer_elem.click() info("Poll successful.") page.wait_for_timeout(3000) # todo check if there is a better method than hardcoded timout