from selenium.webdriver.common.by import By from selenium.webdriver.common.action_chains import ActionChains from selenium.webdriver.common.keys import Keys from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from selenium.common.exceptions import NoAlertPresentException class LiveCodingPage: # ===== LOCATORS ===== PAGE_TITLE = (By.XPATH, "//h4[contains(text(),'Live Coding')]") EXPECTED_OUTPUT = (By.XPATH, "//strong[contains(text(),'Hasil Output')]") CODE_EDITOR = (By.ID, "editor") SUBMIT_BUTTON = (By.ID, "submit-code") ERROR_404_TEXT = "404" #alert / result RESULT_MESSAGE = (By.ID, "result") MODAL = (By.CLASS_NAME, "modal-dialog") CLOSE_BUTTON = (By.XPATH, "//button[normalize-space()='Tutup']") PREVIOUS_BUTTON = (By.XPATH, "//a[contains(text(),'Sebelumnya')]") NEXT_BUTTON = (By.XPATH, "//a[contains(text(),'Selanjutnya')]") OTHER_MENU = (By.XPATH, "//a[contains(@href,'/materi/visual/')]") CONFIRM_MODAL = (By.CLASS_NAME, "modal") CONFIRM_TEXT = (By.CLASS_NAME, "modal-body") def __init__(self, driver): self.driver = driver self.wait = WebDriverWait(driver, 10) # ===== PAGE ACTIONS ===== def is_page_loaded(self): self.wait.until(EC.visibility_of_element_located(self.PAGE_TITLE)) return True def get_expected_output_text(self): return self.driver.find_element(*self.EXPECTED_OUTPUT).text def editor_is_visible(self): return self.driver.find_element(*self.CODE_EDITOR).is_displayed() def append_code(self, code): """ Menambahkan kode ke editor (tanpa menghapus kode bawaan) """ editor = self.driver.find_element(*self.CODE_EDITOR) editor.click() actions = ActionChains(self.driver) actions.key_down(Keys.CONTROL).send_keys(Keys.END).key_up(Keys.CONTROL) actions.send_keys(Keys.ENTER) actions.send_keys(code) actions.perform() def append_code2(self, code): current_code = self.driver.execute_script(""" return monaco.editor.getModels()[0].getValue(); """) updated_code = current_code updated_code = updated_code.replace("...............", " Mahasiswa") updated_code = updated_code.replace(".........", ".println") self.driver.execute_script(""" monaco.editor.getModels()[0].setValue(arguments[0]); """, updated_code) def submit_code(self): btn = WebDriverWait(self.driver, 15).until( EC.element_to_be_clickable(self.SUBMIT_BUTTON) ) self.driver.execute_script( "arguments[0].scrollIntoView({block:'center'});", btn ) self.driver.execute_script("arguments[0].click();", btn) def get_result_message(self): wait = WebDriverWait(self.driver, 20) def result_has_text(driver): el = driver.find_element(By.ID, "result") return el if el.text.strip() != "" else False result_el = wait.until(result_has_text) return result_el.text def close_result_modal(self): WebDriverWait(self.driver, 10).until( EC.element_to_be_clickable(self.CLOSE_BUTTON) ).click() def get_editor_value(self): """ Ambil isi editor Monaco via JavaScript """ return self.driver.execute_script( "return monaco.editor.getModels()[0].getValue();" ) def wait_popup_visible(self): self.wait.until(EC.visibility_of_element_located(self.RESULT_MESSAGE)) def is_popup_visible(self): try: return self.driver.find_element(*self.RESULT_MESSAGE).is_displayed() except: return False def click_previous(self): element = self.driver.find_element(*self.PREVIOUS_BUTTON) self.driver.execute_script("arguments[0].scrollIntoView(true);", element) element.click() def click_next(self): element = self.driver.find_element(*self.NEXT_BUTTON) self.driver.execute_script("arguments[0].scrollIntoView(true);", element) element.click() def wait_popup_invisible(self): WebDriverWait(self.driver, 10).until( EC.invisibility_of_element_located((By.ID, "resultModal")) ) # ===== INFO ===== def get_current_url(self): return self.driver.current_url def is_404_page(self): return self.ERROR_404_TEXT in self.driver.page_source def click_other_menu(self): self.driver.find_element(*self.OTHER_MENU).click() # ===== ALERT HANDLER ===== def is_confirm_alert_present(self): try: alert = self.driver.switch_to.alert return alert.text except NoAlertPresentException: return None # ===== MODAL HANDLER ===== def is_confirm_modal_visible(self): try: return self.driver.find_element(*self.CONFIRM_MODAL).is_displayed() except: return False