class SearchEducationGroupPage(CommonPageMixin, pypom.Page): URL_TEMPLATE = '/educationgroups/' sigleintitule_abrege = InputField(By.ID, 'id_acronym') code = InputField(By.ID, 'id_partial_acronym') anac = SelectField(By.ID, 'id_academic_year') actions = ButtonField(By.ID, 'btn-action') new_training = ButtonField(By.CSS_SELECTOR, '#link_create_training > a', 1) new_mini_training = ButtonField(By.CSS_SELECTOR, '#link_create_mini_training > a', 1) first_row = Link('EducationGroupPage', By.CSS_SELECTOR, '#table_education_groups > tbody > tr:nth-child(1) > td:nth-child(2) > a') type_de_formation = SelectField(By.ID, "id_name") confirm_modal = Link(NewTrainingPage, By.CSS_SELECTOR, '.modal-footer>input.btn-primary') clear_button = ButtonField(By.ID, 'btn_clear_filter') search = Link('SearchEducationGroupPage', By.CSS_SELECTOR, 'button.btn-primary', 1) quick_search = Link(QuickSearchPage, By.ID, 'quick-search', 1) def count_result(self): text = self.find_element( By.CSS_SELECTOR, '#main > div.panel.panel-default > div > div > div.row > div:nth-child(1)').text return text.split()[0]
class LearningUnitAttributionPage(pypom.Page): manage_repartition = Link(RepartitionPage, By.ID, "manage_repartition") save_button = Link('LearningUnitAttributionPage', By.ID, 'save_btn', 3) volume_1 = InputField(By.ID, "id_lecturing_form-allocation_charge") def find_edit_button(self, row): return self.find_element( By.XPATH, '//*[@id="attributions"]/table/tbody/tr[{}]/td[6]/a[1]'.format( row)) def attribution_row(self, row) -> list: result = [] for i in range(1, 7): text = self.find_element( By.XPATH, "//*[@id='attributions']/table/tbody/tr[{}]/td[{}]".format( row, i)).text if text: result.append(text) return result @property def loaded(self): return "Enseignant·e·s" in self.find_element(By.CSS_SELECTOR, 'li.active[role=presentation]').text and \ self.find_element(By.ID, "manage_repartition")
class LearningUnitPage(CommonPageMixin, pypom.Page): actions = ButtonField(By.ID, "dLabel") edit_button = Link('LearningUnitEditPage', By.CSS_SELECTOR, "#link_edit_lu > a") proposal_edit = Link(EditLearningUnitProposalPage, By.CSS_SELECTOR, "#link_proposal_modification > a") edit_proposal_button = Link(EditLearningUnitProposalPage, By.CSS_SELECTOR, "#link_proposal_edit > a") proposal_suppression = Link(LearningUnitProposalEndYearPage, By.CSS_SELECTOR, "#link_proposal_suppression > a") new_partim = Link(NewPartimPage, By.ID, "new_partim") go_to_full = ButtonField(By.ID, "full_acronym") credits = Field(By.ID, "id_credits") annee_academique = Field(By.ID, "id_end_year") tab_training = Link(LearningUnitTrainingPage, By.ID, "training_link") tab_attribution = Link(LearningUnitAttributionPage, By.ID, "attributions_link") tab_description = Link(DescriptionPage, By.ID, "description_link") tab_specification = Link(SpecificationPage, By.ID, "specification_link") def is_li_edit_link_disabled(self): return "disabled" in self.find_element( By.ID, "link_edit_lu").get_attribute("class") @property def loaded(self) -> bool: return "Identification" in self.find_element( By.CSS_SELECTOR, 'li.active[role=presentation]').text
class LearningUnitEditPage(pypom.Page): actif = Checkbox(By.ID, "id_status") periodicite = SelectField(By.ID, "id_periodicity") credits = InputField(By.ID, "id_credits") volume_q1_pour_la_partie_magistrale = InputField(By.ID, "id_component-0-hourly_volume_partial_q1") volume_q1_pour_la_partie_pratique = InputField(By.ID, "id_component-1-hourly_volume_partial_q1") volume_q2_pour_la_partie_magistrale = InputField(By.ID, "id_component-0-hourly_volume_partial_q2") volume_q2_pour_la_partie_pratique = InputField(By.ID, "id_component-1-hourly_volume_partial_q2") quadrimestre = SelectField(By.ID, "id_quadrimester") session_derogation = SelectField(By.ID, "id_session") save_button = ButtonField(By.CSS_SELECTOR, "#main > div.panel.panel-default > div.panel-heading > div > div > div > button") no_postponement = Link(LearningUnitPage, By.ID, "btn_without_postponement") with_postponement = Link(LearningUnitPage, By.ID, "btn_with_postponement")
class NewLearningUnitPage(pypom.Page): _code_0 = SelectField(By.ID, "id_acronym_0") _code_1 = InputField(By.ID, "id_acronym_1") @property def code(self): return self._code_0.text + self._code_1.text @code.setter def code(self, value): self._code_0 = value[0] self._code_1 = value[1:] type = SelectField(By.ID, "id_container_type") credit = InputField(By.ID, "id_credits") credits = InputField(By.ID, "id_credits") lieu_denseignement = SelectField(By.ID, "id_campus") intitule_commun = InputField(By.ID, "id_common_title") entite_resp_cahier_des_charges = Select2Field( By.XPATH, "//*[@id='LearningUnitYearForm']/div[2]/div[1]/div[2]/div/div/div[3]/div/span" ) entite_dattribution = Select2Field( By.XPATH, "//*[@id='LearningUnitYearForm']/div[2]/div[1]/div[2]/div/div/div[4]/div/span" ) save_button = Link("LearningUnitPage", By.ID, 'btn-confirm', 2)
class RepartitionPage(pypom.Page): volume_2 = InputField(By.ID, "id_practical_form-allocation_charge") save_button = Link('LearningUnitAttributionPage', By.ID, 'save_btn') def find_corresponding_button(self, row): return self.find_element( By.XPATH, '//*[@id="attributions"]/table/tbody/tr[{}]/td[6]/a'.format(row))
class NewTrainingPage(pypom.Page): sigleintitule_abrege = InputField(By.ID, 'id_acronym') code = InputField(By.ID, 'id_partial_acronym') intitule_en_francais = InputField(By.ID, 'id_title') entite_de_gestion = SelectEntityVersionField(By.ID, 'id_management_entity') entite_dadministration = SelectEntityVersionField(By.ID, 'id_administration_entity') intitule_du_diplome = InputField(By.ID, 'id_diploma_printing_title') tab_diploma = ButtonField(By.ID, 'lnk_diplomas_certificats') save_button = Link(EducationGroupPage, By.ID, 'btn-confirm', waiting_time=3)
class DescriptionPage(pypom.Page): methode_denseignement = CkeditorField(By.CLASS_NAME, 'cke_wysiwyg_frame') add_button = ButtonField(By.XPATH, '//*[@id="pedagogy"]/div[2]/div[2]/div/a') save_button = Link('DescriptionPage', By.XPATH, '//*[@id="form-modal-ajax-content"]/form/div[3]/button[1]', 2) intitule = InputField(By.ID, 'id_title') support_obligatoire = RadioField(By.ID, 'id_mandatory') def find_edit_button(self, _): return self.find_element(By.XPATH, '//*[@id="pedagogy"]/table[1]/tbody/tr[2]/td[2]/a')
class QuickSearchPage(AjaxModal): code = InputField(By.ID, 'id_search_text') search = ButtonField(By.CSS_SELECTOR, '#form-modal > div > div.col-md-1.col-md-offset-2 > button', 1) select_first = ButtonField( By.CSS_SELECTOR, '#form-modal-ajax-content > div.modal-body > div.row > div > table > tbody > tr > td:nth-child(1) > button' ) lu_tab = ButtonField(By.CSS_SELECTOR, '#form-modal-ajax-content > div.modal-body > ul > li:nth-child(1) > a', 1) eg_tab = ButtonField(By.CSS_SELECTOR, '#form-modal-ajax-content > div.modal-body > ul > li:nth-child(2) > a') close = Link('EducationGroupPage', By.CSS_SELECTOR, '#form-modal-ajax-content > div.modal-header > button')
class SpecificationPage(pypom.Page): themes_abordes = CkeditorField(By.CLASS_NAME, 'cke_wysiwyg_frame') save_button = Link('SpecificationPage', By.CSS_SELECTOR, 'div.modal-footer > .btn-primary', 1) add_button = ButtonField(By.CSS_SELECTOR, '.btn.btn-info.btn-sm.trigger_modal') code = InputField(By.ID, 'id_code_name') texte = CkeditorField(By.CLASS_NAME, 'cke_wysiwyg_frame') up = ButtonField(By.XPATH, '//*[@id="form_achievements"]/div[3]/div[1]/div/button[1]') def find_edit_button(self, _): # TODO hardcoded value for "Thèmes abordés" return self.find_element(By.XPATH, '//*[@id="cms_text_fr_0"]/a')
class SearchLearningUnitPage(CommonPageMixin, pypom.Page): URL_TEMPLATE = '/learning_units/by_activity/' proposal_search = Link('SearchLearningUnitPage', By.ID, 'lnk_proposal_search', 1) anac = SelectField(By.ID, 'id_academic_year_id') acronym = InputField(By.ID, 'id_acronym') code = InputField(By.ID, 'id_acronym') tutor = InputField(By.ID, 'id_tutor') sigle_dossier = SelectField(By.ID, "id_entity_folder_id") requirement_entity = InputField(By.ID, 'id_requirement_entity_acronym') ent_charge = InputField(By.ID, 'id_requirement_entity_acronym') container_type = SelectField(By.ID, 'id_container_type') clear_button = ButtonField(By.ID, 'btn_clear_filter') search = Link('SearchLearningUnitPage', By.CSS_SELECTOR, 'button.btn-primary', 2) export = ButtonField(By.ID, "dLabel") list_learning_units = ButtonField(By.ID, "btn_produce_xls_with_parameters") with_program = ButtonField(By.ID, "chb_with_grp") with_tutor = ButtonField(By.ID, "chb_with_attributions") generate_xls = ButtonField(By.ID, "btn_xls_with_parameters") actions = ButtonField(By.ID, 'btn-action') new_luy = Link(NewLearningUnitPage, By.ID, 'lnk_learning_unit_create') create_proposal_url = Link(NewLearningUnitProposalPage, By.ID, 'lnk_create_proposal_url') # TODO this action is really slow. back_to_initial_yes = Link( 'SearchLearningUnitPage', By.CSS_SELECTOR, '#modalBackToInitial > div > div > div.modal-footer > button.btn.btn-primary', 4) consolidate_yes = Link( 'SearchLearningUnitPage', By.CSS_SELECTOR, '#modalConsolidate > div > div > div.modal-footer > button.btn.btn-primary', 4) def count_result(self): text = self.find_element( By.CSS_SELECTOR, "#main > div.panel.panel-default > div > strong").text return text.split()[0] def find_acronym_in_table(self, row: int = 1): selector = '#table_learning_units > tbody > tr:nth-child({}) > td.col-acronym > a'.format( row) return self.find_element(By.CSS_SELECTOR, selector).text
class EducationGroupPage(CommonPageMixin, pypom.Page): sigleintitule_abrege = Field( By.CSS_SELECTOR, '#identification > div > div > div.row > div.col-md-7 > div:nth-child(1) > div > div.row > dl:nth-child(1) > dd' ) code = Field( By.CSS_SELECTOR, '#identification > div > div > div.row > div.col-md-7 > div:nth-child(1) > div > div.row > dl:nth-child(2) > dd' ) entite_de_gestion = Field( By.CSS_SELECTOR, '#identification > div > div > div.row > div.col-md-5 > div:nth-child(1) > div > dl:nth-child(1) > dd' ) entite_dadministration = Field( By.CSS_SELECTOR, '#identification > div > div > div.row > div.col-md-5 > div:nth-child(1) > div > dl:nth-child(2) > dd' ) actions = ButtonField(By.ID, 'dLabel') modify = Link('UpdateTrainingPage', By.CSS_SELECTOR, '#link_update > a', 1) delete = ButtonField(By.CSS_SELECTOR, '#link_delete > a', 1) select_first = ButtonField(By.CSS_SELECTOR, "#select_li > a", 1) confirm_modal = Link('SearchEducationGroupPage', By.CSS_SELECTOR, '.modal-footer>input[type=submit]') toggle_tree = ButtonField(By.CSS_SELECTOR, '#panel-data > div.panel-heading > div > a') open_first_node_tree = ButtonField(By.CSS_SELECTOR, '#panel_file_tree > ul > li > i') quick_search = Link(QuickSearchPage, By.ID, 'quick-search', 1) save_modal = Link('EducationGroupPage', By.CSS_SELECTOR, '.modal-footer > .btn-primary', 4) attach = Link(CopyModalPage, By.CSS_SELECTOR, 'body > ul > li:nth-child(5) > a', 2) detach = Link(DetachModalPage, By.CSS_SELECTOR, 'body > ul > li:nth-child(6) > a', 2) def get_name_first_children(self) -> list: children = self.find_elements(By.CSS_SELECTOR, '#panel_file_tree > ul > li > ul > li') return [child.text for child in children] def find_node_tree_by_acronym(self, acronym, parent=None): if not parent: parent = self else: parent = self.find_node_tree_by_acronym(parent) for node in parent.find_elements(By.CSS_SELECTOR, 'li.jstree-node'): if acronym == node.text.split('-')[0].strip(): return node raise Exception("Node not found") def open_node_tree_by_acronym(self, acronym): node = self.find_node_tree_by_acronym(acronym) node.find_element(By.CSS_SELECTOR, 'i').click() def rigth_click_node_tree(self, acronym, parent=None): node = self.find_node_tree_by_acronym(acronym, parent) actionChains = ActionChains(self.driver) child = node.find_element(By.CSS_SELECTOR, 'a') actionChains.context_click(child).perform() return child def attach_node_tree(self, acronym, parent=None): self.rigth_click_node_tree(acronym, parent) return self.attach.click() def detach_node_tree(self, acronym, parent=None): self.rigth_click_node_tree(acronym, parent) return self.detach.click() def select_node_tree(self, acronym, parent=None): self.rigth_click_node_tree(acronym, parent) self.find_element(By.CSS_SELECTOR, 'body > ul > li:nth-child(1) > a').click() time.sleep(1) @property def loaded(self) -> bool: return "Identification" in self.find_element( By.CSS_SELECTOR, 'li.active[role=presentation]' ).text and not self.find_element(By.ID, 'modal_dialog_id').is_displayed()
class AttachModalPage(AjaxModal): type_de_lien = SelectField(By.ID, 'id_link_type') save_modal = Link('EducationGroupPage', By.CSS_SELECTOR, '.modal-footer > .btn-primary', 6)
class DetachModalPage(AjaxModal): save_modal = Link('EducationGroupPage', By.CSS_SELECTOR, '.modal-footer > .btn-danger', 6)
class CopyModalPage(AjaxModal): copy_btn = Link('AttachModalPage', By.CSS_SELECTOR, '.modal-footer > .btn-primary', 1)