From 85880c8a036057b77285d0c5db27969188dab2ff Mon Sep 17 00:00:00 2001 From: Chris Date: Thu, 18 Jun 2026 15:25:43 +0200 Subject: [PATCH 1/2] PARAF-166: Updated robotframework tests to include electronic signature --- CHANGES.rst | 2 + imio/dms/mail/tests/robot/doc.robot | 223 +++++++++++++++++++++++++++- 2 files changed, 220 insertions(+), 5 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index d138c967a..50610d1c3 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -13,6 +13,8 @@ Changelog [chris-adam] - Considered seal when checking if a signer is defined on a sub/template. [sgeulette] +- Updated robotframework tests to include electronic signature (PARAF-166, DMS-434). + [chris-adam] 3.1.5 (2026-06-19) ------------------ diff --git a/imio/dms/mail/tests/robot/doc.robot b/imio/dms/mail/tests/robot/doc.robot index e4883c580..eb8b1050f 100644 --- a/imio/dms/mail/tests/robot/doc.robot +++ b/imio/dms/mail/tests/robot/doc.robot @@ -14,6 +14,8 @@ Suite Teardown Close all browsers #${BROWSER} = GoogleChrome ${SELENIUM_RUN_ON_FAILURE} = Debug +# Delay (seconds) added after each Selenium action. Override to watch a run, e.g. -v SELENIUM_SPEED:1.0 +${SELENIUM_SPEED} = 0.2 *** Test Cases *** @@ -194,6 +196,7 @@ CE numerisation Select from list by value id=form-widgets-original_mail_date-day 6 Select from list by value id=form-widgets-original_mail_date-month 6 Select from list by value id=form-widgets-original_mail_date-year 2012 + Select checkbox id=form-widgets-send_modes-0 Capture and crop page screenshot doc/utilisation/2-2-1-edition-courrier-fini.png id=content Click button id=form-buttons-save Sleep 2 @@ -324,6 +327,7 @@ CS en réponse Set field value ${UID} recipient_groups ['${DF}'] list Set field value ${UID} assigned_user agent str Set field value ${UID} external_reference_no 2017/ESB/00123 str + Set field value ${UID} send_modes ['post'] list Go to ${PLONE_URL}/${im_path}/edit Click button id=form-buttons-save Fire transition ${UID} propose_to_n_plus_1 @@ -367,7 +371,7 @@ CS en réponse Sleep 1 Wait until element is visible css=.DV-pageImage 10 Capture and crop page screenshot doc/utilisation/2-3-1-cs-3-ged-genere.png id=content - ${note52} Add pointy note css=#fieldset-versions tr.selected td:nth-child(3) Édition externe position=top color=blue + ${note52} Add pointy note css=#fieldset-versions tr.selected a.apButtonAction_form_external_edit Édition externe position=top color=blue Capture and crop page screenshot doc/utilisation/2-3-1-cs-3-ged-edition-externe.png css=#fieldset-versions table ${note52} Remove element id=${note52} Delete content /plone/${om_path}/012999900000001 @@ -392,10 +396,10 @@ CS en réponse Sleep 1 Wait until element is visible css=.DV-pageImage 10 Capture and crop page screenshot doc/utilisation/2-3-1-cs-4-ged-genere-non-pub.png id=content - ${note55} Add pointy note css=#fieldset-versions tr.selected td:nth-child(6) Publipostage position=top color=blue + ${note55} Add pointy note css=#fieldset-versions tr.selected a.apButtonAction_form_mailing Publipostage position=left color=blue Capture and crop page screenshot doc/utilisation/2-3-1-cs-4-ged-publipostage.png css=#fieldset-versions table ${note55} Remove element id=${note55} - Click element css=#fieldset-versions tr.selected td:nth-child(6) + Click element css=#fieldset-versions tr.selected a.apButtonAction_form_mailing Sleep 5 Go to ${PLONE_URL}/${om_path} Sleep 1 @@ -488,8 +492,11 @@ CS nouveau Click button id=form-buttons-save # Set field value ${UID} email_body

Bonjour Monsieur,

Vous trouverez en pièce jointe un document concernant la réfection des trottoirs dans votre rue.

Cordialement

 

Fred Agent

 

Agent Voiries
Direction technique
Voiries
fred.agent@macommune.be
012/34.56.70
Rue de la commune, 1
0010 Ma ville

Administration communale de Belleville

 


Limite de responsabilité: les informations contenues dans ce courrier électronique (annexes incluses) sont confidentielles et réservées à l'usage exclusif des destinataires repris ci-dessus. Si vous n'êtes pas le destinataire, soyez informé par la présente que vous ne pouvez ni divulguer, ni reproduire, ni faire usage de ces informations pour vous-même ou toute tierce personne. Si vous avez reçu ce courrier électronique par erreur, vous êtes prié d'en avertir immédiatement l'expéditeur et d'effacer le message e-mail de votre ordinateur.
text/html # Go to ${PLONE_URL}/${om_path} + Set Window Size 1300 2200 Wait until element is visible css=#viewlet-below-content-body table.actionspanel-no-style-table 10 Capture and crop page screenshot doc/utilisation/2-3-4-cs-email-visualisation.png css=table.actionspanel-no-style-table id=fieldset-versions id=form-groups-email + # Restore window size + Set Window Size 1200 1920 # Click element css=input.apButtonAction_sendemail # not working on test env CS depuis le scanner @@ -1151,7 +1158,7 @@ Gestion modèles Wait until element is visible form-widgets-merge_templates 10 Update element style css=#formfield-form-widgets-pod_portal_types display None ${note43} Add pointy note css=#form-widgets-merge_templates tbody tr:first-child td:nth-last-child(2) Ajouter ou supprimer des sous-modèles position=left color=blue - ${note44} Add pointy note css=#form-widgets-merge_templates-4-widgets-template Choisir le sous-modèle à fusionner position=bottom color=blue + ${note44} Add pointy note css=#form-widgets-merge_templates tr.auto-append [id$=-widgets-template] Choisir le sous-modèle à fusionner position=bottom color=blue Capture and crop page screenshot doc/utilisation/2-10-2-fusion-sous-modeles.png css=#form-widgets-merge_templates id=${note44} Remove element id=${note43} Remove element id=${note44} @@ -1379,6 +1386,168 @@ Annexes dossiers Go to ${PLONE_URL}/folders/ Click Element css:.pretty_link_content.state-active +Signature écrite +# partie 2.13.1 Mise à la signature manuscrite + [TAGS] RUN2131 + Activate esigning + Enable autologin as encodeur + Show connected user Jean Encodeur (service encodeur) 2-13-1-user-encodeur.png + ${om_path} = Add outgoing mail for signing Décision de voirie à signer manuellement + ${UID} = Path to uid /${PLONE_SITE_ID}/${om_path} + # Signataires : préremplis par les règles de signature (configuration administrateur) : + # Directeur Général (utilisateur "dirg") et Bourgmestre, tous deux SANS approbation et SANS + # signature électronique. + Wait until element is visible css=#viewlet-below-content-body table.actionspanel-no-style-table 10 + Wait until element is visible id=form-groups-signing 10 + ${note1} Add pointy note id=formfield-form-widgets-ISigningBehavior-signers Signataires (sans approbation) position=top color=blue + Capture and crop page screenshot doc/utilisation/2-13-1-signataires.png id=form-groups-signing ${note1} + Remove element id=${note1} + ${note2} Add pointy note id=formfield-form-widgets-ISigningBehavior-esign Signature électronique désactivée position=top color=blue + Capture and crop page screenshot doc/utilisation/2-13-1-signature-electronique-off.png id=form-groups-signing ${note2} + Remove element id=${note2} + # Génération d'un fichier ged depuis un modèle + Capture and crop page screenshot doc/utilisation/2-13-1-generation-modele.png css=#parent-fieldname-title span.pretty_link_content + ${TPL} = Path to uid /${PLONE_SITE_ID}/templates/om/main + Go to ${PLONE_URL}/${om_path}/persistent-document-generation?template_uid=${TPL}&output_format=odt + Sleep 2 + Go to ${PLONE_URL}/${om_path} + Sleep 1 + Wait until element is visible css=.DV-pageImage 10 + Capture and crop page screenshot doc/utilisation/2-13-1-courrier-genere.png id=content + # Mise à la signature manuscrite (état "to_be_signed"). + # created -> to_be_validated (encodeur) -> to_be_signed (chef) + Fire transition ${UID} propose_to_n_plus_1 + Enable autologin as chef + Fire transition ${UID} propose_to_be_signed + Go to ${PLONE_URL}/${om_path} + Sleep 0.5 + Wait until element is visible css=.DV-pageImage 10 + Show connected user Michel Chef (responsable de service, n+1) 2-13-1-user-chef.png + Capture and crop page screenshot doc/utilisation/2-13-1-a-la-signature.png css=div.viewlet_workflowstate css=table.actionspanel-no-style-table + # Scan step not automatable in RF: auto-transition to sent requires physical scan. + ${note4} Add pointy note css=div.viewlet_workflowstate Numérisation du document signé (scan papier) puis envoi position=bottom color=blue + Capture and crop page screenshot doc/utilisation/2-13-1-etape-numerisation.png css=div.viewlet_workflowstate ${note4} + Remove element id=${note4} + +Signature électronique +# partie 2.13.2 Mise à l'approbation et signature électronique + [TAGS] RUN2132 + Activate esigning + Enable autologin as encodeur + Show connected user Jean Encodeur (service encodeur) 2-13-2-user-encodeur.png + ${om_path} = Add outgoing mail for signing Décision de voirie à signer electroniquement + ${UID} = Path to uid /${PLONE_SITE_ID}/${om_path} + # Édition du panneau de signature. Les signataires (Directeur Général + Bourgmestre) ont été + # préremplis par la configuration administrateur (règles de signature). + Wait until element is visible css=#viewlet-below-content-body table.actionspanel-no-style-table 10 + # Clic sur l'icône d'édition présente dans la légende du fieldset "Signature" + Wait until element is visible css=#form-groups-signing legend a[href*='/edit#fieldsetlegend-signing'] 10 + ${note_edit} Add pointy note css=#form-groups-signing legend a[href*='/edit#fieldsetlegend-signing'] Icône d'édition du panneau de signature position=top color=blue + Capture and crop page screenshot doc/utilisation/2-13-2-icone-edition-signature.png id=form-groups-signing ${note_edit} + Remove element id=${note_edit} + Click element css=#form-groups-signing legend a[href*='/edit#fieldsetlegend-signing'] + Sleep 0.5 + Wait until element is visible id=fieldsetlegend-signing 10 + Click element id=fieldsetlegend-signing + Sleep 0.5 + ${note0} Add pointy note id=formfield-form-widgets-ISigningBehavior-signers Signataires préremplis par la configuration position=top color=blue + Capture and crop page screenshot doc/utilisation/2-13-2-signataires-preremplis.png id=fieldset-signing ${note0} + Remove element id=${note0} + # Approbation par lui-même pour chaque signataire (on décoche "Aucune approbation", on coche "Lui-même") + Unselect checkbox id=form-widgets-ISigningBehavior-signers-0-widgets-approvings-0 + Select checkbox id=form-widgets-ISigningBehavior-signers-0-widgets-approvings-1 + Unselect checkbox id=form-widgets-ISigningBehavior-signers-1-widgets-approvings-0 + Select checkbox id=form-widgets-ISigningBehavior-signers-1-widgets-approvings-1 + ${note1} Add pointy note id=formfield-form-widgets-ISigningBehavior-signers Approbation activée pour chaque signataire position=top color=blue + Capture and crop page screenshot doc/utilisation/2-13-2-approbation.png id=fieldset-signing ${note1} + Remove element id=${note1} + Select checkbox id=form-widgets-ISigningBehavior-esign-0 + ${note2} Add pointy note id=formfield-form-widgets-ISigningBehavior-esign Signature électronique activée position=top color=blue + Capture and crop page screenshot doc/utilisation/2-13-2-signature-electronique-on.png id=fieldset-signing ${note2} + Remove element id=${note2} + Click button id=form-buttons-save + Wait until element is visible css=#viewlet-below-content-body table.actionspanel-no-style-table 10 + ${TPL} = Path to uid /${PLONE_SITE_ID}/templates/om/main + Go to ${PLONE_URL}/${om_path}/persistent-document-generation?template_uid=${TPL}&output_format=odt + Sleep 2 + # Mise à l'approbation : proposition au n+1 (par l'encodeur) puis passage à l'approbation (par le chef, n+1). + Fire transition ${UID} propose_to_n_plus_1 + Enable autologin as chef + Fire transition ${UID} propose_to_approve + Go to ${PLONE_URL}/${om_path} + Sleep 0.5 + Wait until element is visible css=.DV-pageImage 10 + Show connected user Michel Chef (responsable de service, n+1) 2-13-2-user-chef.png + Capture and crop page screenshot doc/utilisation/2-13-2-a-approuver.png css=div.viewlet_workflowstate id=fieldset-versions + # Approbation par le premier approbateur (Directeur Général / dirg) + Enable autologin as dirg + Go to ${PLONE_URL}/${om_path} + Sleep 0.5 + Wait until element is visible css=#fieldset-versions td.iconified-approved a.iconified-action.editable 10 + Show connected user Maxime DG (Directeur Général, 1er approbateur) 2-13-2-user-dirg.png + # Mode lecture + Wait until element is visible css=.DV-pageImage 10 + Wait until element is visible id=read_mode_icon 10 + ${note_rm} Add pointy note id=read_mode_icon Bouton "mode lecture" pour afficher le document en plein écran position=bottom color=blue + Capture and crop page screenshot doc/utilisation/2-13-2-icone-mode-lecture.png id=portal-globalnav ${note_rm} + Remove element id=${note_rm} + Click element id=read_mode_icon + Wait until element is visible css=body.read-mode 10 + Sleep 1 + Capture and crop page screenshot doc/utilisation/2-13-2-mode-lecture.png id=content + # Sortie du mode lecture + Click element id=read_mode_icon + Sleep 0.5 + Delete Cookie dms_document_view + Add Cookie dv_zoom_size 500 path=/ + Go to ${PLONE_URL}/${om_path} + Sleep 0.5 + Wait until element is visible css=#fieldset-versions td.iconified-approved a.iconified-action.editable 10 + ${note3} Add pointy note css=#fieldset-versions td.iconified-approved a.iconified-action.editable Icône d'approbation position=top color=blue + Capture and crop page screenshot doc/utilisation/2-13-2-icone-approbation.png id=fieldset-versions ${note3} + Remove element id=${note3} + Click element css=#fieldset-versions td.iconified-approved a.iconified-action.editable + Sleep 1 + # Approbation par le second approbateur (Bourgmestre) + Enable autologin as bourgmestre + Go to ${PLONE_URL}/${om_path} + Sleep 0.5 + Wait until element is visible css=#fieldset-versions td.iconified-approved a.iconified-action.editable 10 + Show connected user Paul BM (Bourgmestre, 2e approbateur) 2-13-2-user-bourgmestre.png + Click element css=#fieldset-versions td.iconified-approved a.iconified-action.editable + Sleep 1 + # Une session eSign a été créée à l'état "En création" ; le courrier passe automatiquement à la signature + Enable autologin as Manager + Set autologin username dirg + Go to ${PLONE_URL}/${om_path} + Sleep 0.5 + Wait until element is visible css=span.state-title-draft 10 + Show connected user Gestionnaire de signatures 2-13-2-user-gestionnaire.png + ${note4} Add pointy note css=span.state-title-draft Session eSign en cours de création position=bottom color=blue + Capture and crop page screenshot doc/utilisation/2-13-2-session-en-creation.png id=session-info ${note4} + Remove element id=${note4} + Wait until page contains element css=#fieldset-versions a.version-link[title*=".pdf"] 10 + ${note_pdf} Add pointy note css=#fieldset-versions a.version-link[title*=".pdf"] Un document PDF a été généré pour la signature position=top color=blue + Capture and crop page screenshot doc/utilisation/2-13-2-pdf-genere-signature.png id=fieldset-versions ${note_pdf} + Remove element id=${note_pdf} + # Onglet Paraphéo + Wait until element is visible id=portaltab-parapheo 10 + ${note5} Add pointy note id=portaltab-parapheo Onglet Paraphéo position=bottom color=blue + Capture and crop page screenshot doc/utilisation/2-13-2-onglet-parapheo.png id=portal-globalnav ${note5} + Remove element id=${note5} + Click element id=portaltab-parapheo + Wait until element is visible css=img[onclick*="external-esign-session-create"] 10 + # Resize the window to show the actions column + Set Window Size 2200 1920 + Sleep 0.5 + Wait until element is visible css=img[onclick*="external-esign-session-create"] 10 + ${note6} Add pointy note css=img[onclick*="external-esign-session-create"] Bouton de création de session externe position=left color=blue + Capture and crop page screenshot doc/utilisation/2-13-2-creation-session-externe.png id=content ${note6} + Sleep 0.5 + Remove element id=${note6} + # Restore window size + Set Window Size 1200 1920 + Debug [TAGS] DBG Pass execution Only for debug purpose @@ -1398,9 +1567,53 @@ Suite Setup Set Window Size 1200 1920 Set Suite Variable ${CROP_MARGIN} 5 Set Selenium Implicit Wait 2 - Set Selenium Speed 0.2 + Set Selenium Speed ${SELENIUM_SPEED} Enable autologin as Manager Set autologin username dirg Go to ${PLONE_URL}/robot_init + Add Cookie dv_zoom_size 500 path=/ Disable autologin # Pause + +Activate esigning + [Documentation] Active la signature/approbation électronique (profil singles). + ... N'est appelé que dans les tests 2.13.1 / 2.13.2 : pour tous les autres tests, la + ... signature reste désactivée. + Enable autologin as Manager + Set autologin username dirg + Apply profile step imio.dms.mail:singles imiodmsmail-activate-esigning + Disable autologin + +Show connected user + [Documentation] Display a top banner naming the currently connected user (so a video viewer + ... always knows who is acting), capture a screenshot, then remove the banner. + [Arguments] ${name} ${shot} + ${unote} Add main note Connecté en tant que : ${name} + Capture and crop page screenshot doc/utilisation/${shot} id=portal-top ${unote} + Remove element id=${unote} + +Add outgoing mail for signing + [Documentation] Create an outgoing mail (as the current user) filling every required field + ... (title, recipients, send_modes via UI ; treating_groups and sender). + ... Returns the mail relative path. + [Arguments] ${title} + Go to ${PLONE_URL}/outgoing-mail + Wait until element is visible newOMCreation 10 + Click element newOMCreation + Wait until element is visible css=.template-dmsoutgoingmail #formfield-form-widgets-sender 10 + Sleep 0.5 + Create content type=person container=/${PLONE_SITE_ID}/contacts firstname=Dale lastname=Cooper zip_code=4000 city=Belleville street=Rue Moyenne number=1991 email=dale.cooper@twinpeaks.com + Input text name=form.widgets.IDublinCore.title ${title} + Input text name=form.widgets.recipients.widgets.query cooper + Wait until element is visible css=.ac_results:not([style*="display: none"]) 10 + Click element css=.ac_results:not([style*="display: none"]) li + Select checkbox id=form-widgets-send_modes-0 + Click button id=form-buttons-save + Wait until element is visible css=#viewlet-below-content-body table.actionspanel-no-style-table 10 + ${om_path} = Get mail path ptype=dmsoutgoingmail title=${title} + ${UID} = Path to uid /${PLONE_SITE_ID}/${om_path} + ${TG} = Path to uid /${PLONE_SITE_ID}/contacts/plonegroup-organization/direction-generale/grh + Set field value ${UID} treating_groups ${TG} str + ${SENDER} = Path to uid /${PLONE_SITE_ID}/contacts/personnel-folder/agent/agent-grh + Set field value ${UID} sender ${SENDER} str + [Return] ${om_path} From 4eaf059fb36319b209efe3b9f15a0d9829c2ea03 Mon Sep 17 00:00:00 2001 From: Chris Date: Thu, 2 Jul 2026 14:34:29 +0200 Subject: [PATCH 2/2] DMS-434: Fixed ConnectionStateError crash when rendering datagrid fields in settings through robotframework tests --- CHANGES.rst | 5 ++++- imio/dms/mail/browser/settings.py | 26 ++++++++++++++++++++++++++ imio/dms/mail/tests/robot/doc.robot | 18 ++++++++---------- 3 files changed, 38 insertions(+), 11 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index 50610d1c3..c123386d3 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -13,7 +13,10 @@ Changelog [chris-adam] - Considered seal when checking if a signer is defined on a sub/template. [sgeulette] -- Updated robotframework tests to include electronic signature (PARAF-166, DMS-434). +- Updated robotframework tests to include electronic signature (PARAF-166). + [chris-adam] +- Fixed ``ConnectionStateError`` crash when rendering datagrid fields + in settings through robotframework tests (DMS-434). [chris-adam] 3.1.5 (2026-06-19) diff --git a/imio/dms/mail/browser/settings.py b/imio/dms/mail/browser/settings.py index 5de790e26..897863d72 100644 --- a/imio/dms/mail/browser/settings.py +++ b/imio/dms/mail/browser/settings.py @@ -48,6 +48,7 @@ # from z3c.form.browser.radio import RadioFieldWidget # from z3c.form.interfaces import WidgetActionExecutionError from z3c.form.validator import NoInputData +from ZODB.POSException import ConnectionStateError from zope import schema from zope.component import getUtility from zope.globalrequest import getRequest @@ -1245,7 +1246,32 @@ class SettingsEditForm(RegistryEditForm): form.extends(RegistryEditForm) schema = IImioDmsMailConfig + _datagrid_row_schemas = { + "mail_types": ITableListSchema, + "imail_fields": IIMFieldsSchema, + "imail_send_modes": ITableListSchema, + "iemail_routing": IRoutingSchema, + "iemail_state_set": IStateSetSchema, + "omail_types": ITableListSchema, + "omail_send_modes": ITableListSchema, + "omail_signer_substitutes": ISignerSubstituteSchema, + "omail_signer_rules": ISignerRuleSchema, + "omail_fields": IOMFieldsSchema, + } + + def _heal_datagrid_value_types(self): + for name, row_schema in self._datagrid_row_schemas.items(): + field = self.schema.get(name) + if field is None or getattr(field, "value_type", None) is None: + continue + try: + field.value_type.schema + except ConnectionStateError: + logger.warn("DMS-434: rebuilding stale datagrid value_type for %r", name) + field.value_type = DictRow(title=field.title, schema=row_schema, required=False) + def update(self): + self._heal_datagrid_value_types() super(SettingsEditForm, self).update() # !! groups are updated outside and after updateWidgets # we will display unconfigured fields diff --git a/imio/dms/mail/tests/robot/doc.robot b/imio/dms/mail/tests/robot/doc.robot index eb8b1050f..20bfe845e 100644 --- a/imio/dms/mail/tests/robot/doc.robot +++ b/imio/dms/mail/tests/robot/doc.robot @@ -1207,16 +1207,14 @@ Configuration Click element id=fieldsetlegend-outgoingmail Wait until element is visible id=formfield-form-widgets-outgoingmail_number 10 Capture and crop page screenshot doc/configuration/5-3-config-courrier-cs.png id=content - # Erreur chargement page, voir https://support.imio.be/browse/DMS-434 - #Go to ${PLONE_URL}/@@imiodmsmail-settings - #Wait until element is visible id=formfield-form-widgets-mail_types 10 - # TO DO MANUALLY - #Capture and crop page screenshot doc/configuration/5-3-config-courrier-2-ce.png id=content - #Capture and crop page screenshot doc/configuration/5-3-config-courrier-2-cs.png id=content - #Capture and crop page screenshot doc/configuration/5-3-config-courrier-2-contacts.png id=content - #Go to ${PLONE_URL}/@@contact-plonegroup-settings - #Wait until element is visible id=pg-orga-link 10 - #Capture and crop page screenshot doc/configuration/5-4-config-services.png id=content + Go to ${PLONE_URL}/@@imiodmsmail-settings + Wait until element is visible id=formfield-form-widgets-mail_types 10 + Capture and crop page screenshot doc/configuration/5-3-config-courrier-2-ce.png id=content + Capture and crop page screenshot doc/configuration/5-3-config-courrier-2-cs.png id=content + Capture and crop page screenshot doc/configuration/5-3-config-courrier-2-contacts.png id=content + Go to ${PLONE_URL}/@@contact-plonegroup-settings + Wait until element is visible id=pg-orga-link 10 + Capture and crop page screenshot doc/configuration/5-4-config-services.png id=content # services Go to ${PLONE_URL}/contacts/plonegroup-organization Wait until element is visible css=table.suborganizations-listing 10