This is an automated email from the ASF dual-hosted git repository.

sbp pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/tooling-trusted-release.git


The following commit(s) were added to refs/heads/main by this push:
     new 08471cf  Update browser tests and fix key display problems
08471cf is described below

commit 08471cf344a5720b8ae6346c90d6135fa7f34b04
Author: Sean B. Palmer <[email protected]>
AuthorDate: Wed Jun 18 17:10:53 2025 +0100

    Update browser tests and fix key display problems
---
 atr/db/interaction.py           |  4 ++-
 atr/routes/keys.py              |  3 ++
 atr/tasks/checks/signature.py   |  3 ++
 atr/templates/keys-details.html |  2 +-
 atr/templates/keys-review.html  |  2 +-
 playwright/test.py              | 74 ++++++++++++-----------------------------
 6 files changed, 33 insertions(+), 55 deletions(-)

diff --git a/atr/db/interaction.py b/atr/db/interaction.py
index e4cbf77..3e935ea 100644
--- a/atr/db/interaction.py
+++ b/atr/db/interaction.py
@@ -158,7 +158,9 @@ async def key_user_session_add(
                 existing.primary_declared_uid = uids[0] if uids else None
                 existing.secondary_declared_uids = uids[1:]
                 existing.apache_uid = asf_uid
-                existing.ascii_armored_key = public_key
+                existing.ascii_armored_key = (
+                    public_key.decode("utf-8", errors="replace") if 
isinstance(public_key, bytes) else public_key
+                )
                 logging.info(f"Found existing key {fingerprint.upper()}, 
updating associations")
             else:
                 logging.info(f"Found existing key {fingerprint.upper()}, no 
update needed")
diff --git a/atr/routes/keys.py b/atr/routes/keys.py
index 4d7b6f4..246ae7f 100644
--- a/atr/routes/keys.py
+++ b/atr/routes/keys.py
@@ -313,6 +313,9 @@ async def details(session: routes.CommitterSession, 
fingerprint: str) -> str | r
             await quart.flash("Key committee associations updated 
successfully.", "success")
             return await session.redirect(details, fingerprint=fingerprint)
 
+    if isinstance(key.ascii_armored_key, bytes):
+        key.ascii_armored_key = key.ascii_armored_key.decode("utf-8", 
errors="replace")
+
     return await template.render(
         "keys-details.html",
         key=key,
diff --git a/atr/tasks/checks/signature.py b/atr/tasks/checks/signature.py
index 51766ea..3ee9963 100644
--- a/atr/tasks/checks/signature.py
+++ b/atr/tasks/checks/signature.py
@@ -105,6 +105,9 @@ async def _check_core_logic(committee_name: str, 
artifact_path: str, signature_p
                         apache_uid_map[key.fingerprint.lower()] = True
 
     public_keys = [key.ascii_armored_key for key in db_public_keys]
+    for i, key in enumerate(public_keys):
+        if isinstance(key, bytes):
+            public_keys[i] = key.decode("utf-8", errors="replace")
 
     return await asyncio.to_thread(
         _check_core_logic_verify_signature,
diff --git a/atr/templates/keys-details.html b/atr/templates/keys-details.html
index f7840d9..08bce30 100644
--- a/atr/templates/keys-details.html
+++ b/atr/templates/keys-details.html
@@ -103,6 +103,6 @@
     </tbody>
   </table>
   <h2>ASCII armored key</h2>
-  <pre class="mt-3 border border-2 p-3">{{ key.ascii_armored_key if 
isinstance(key.ascii_armored_key, str) else 
key.ascii_armored_key.decode('utf-8') }}</pre>
+  <pre class="mt-3 border border-2 p-3">{{ key.ascii_armored_key }}</pre>
   {# TODO: Add download button for the ASCII armored key #}
 {% endblock content %}
diff --git a/atr/templates/keys-review.html b/atr/templates/keys-review.html
index f3698c9..ed70c86 100644
--- a/atr/templates/keys-review.html
+++ b/atr/templates/keys-review.html
@@ -39,7 +39,7 @@
         </thead>
         <tbody>
           {% for key in user_keys %}
-            <tr>
+            <tr class="page-user-openpgp-key">
               <td class="text-break px-2 align-middle">
                 <a href="{{ as_url(routes.keys.details, 
fingerprint=key.fingerprint) }}">{{ key.fingerprint[-16:]|upper }}</a>
               </td>
diff --git a/playwright/test.py b/playwright/test.py
index d9d00bc..c8a2952 100644
--- a/playwright/test.py
+++ b/playwright/test.py
@@ -745,8 +745,8 @@ def test_openpgp_01_upload(page: sync_api.Page, 
credentials: Credentials) -> Non
     go_to_path(page, "/keys")
 
     logging.info(f"Verifying OpenPGP key with fingerprint 
{key_fingerprint_upper} is visible")
-    key_card_locator = 
page.locator(f'div.card:has(td:has-text("{key_fingerprint_upper}"))')
-    sync_api.expect(key_card_locator).to_be_visible()
+    key_row_locator = 
page.locator(f'tr.page-user-openpgp-key:has(a[href="/keys/details/{key_fingerprint_lower}"])')
+    sync_api.expect(key_row_locator).to_be_visible()
     logging.info("OpenPGP key fingerprint verified successfully on /keys page")
 
 
@@ -1075,63 +1075,33 @@ def test_tidy_up_openpgp_keys(page: sync_api.Page) -> 
None:
     logging.info("Navigated to /keys page for OpenPGP key cleanup")
 
     openpgp_key_section_locator = page.locator("h3:has-text('OpenPGP keys')")
-    key_cards_container_locator = openpgp_key_section_locator.locator(
-        "xpath=following-sibling::div[contains(@class, 
'mb-5')]//div[contains(@class, 'd-grid')]"
-    )
-    key_cards_locator = key_cards_container_locator.locator("> div.card")
+    table_locator = 
openpgp_key_section_locator.locator("xpath=following-sibling::div//table")
+    key_rows_locator = table_locator.locator("tbody tr.page-user-openpgp-key")
 
-    key_cards = key_cards_locator.all()
-    logging.info(f"Found {len(key_cards)} potential OpenPGP key cards to 
check")
+    key_rows = key_rows_locator.all()
+    logging.info(f"Found {len(key_rows)} OpenPGP key rows to check")
 
     fingerprints_to_delete = []
 
-    for card in key_cards:
-        details_element = card.locator("details").first
-        summary_element = details_element.locator("summary").first
-
-        if not details_element.is_visible(timeout=500):
-            logging.warning("OpenPGP key card: <details> element not found or 
not visible, skipping")
-            continue
-        if not summary_element.is_visible(timeout=500):
-            logging.warning("OpenPGP key card: <summary> element not found or 
not visible, skipping")
+    for row in key_rows:
+        link_locator = row.locator('a[href^="/keys/details/"]')
+        href = link_locator.get_attribute("href")
+        if not href:
+            logging.warning("Could not find href for key details link in a 
row, skipping")
             continue
+        fingerprint = href.split("/")[-1]
 
-        is_already_open = details_element.evaluate("el => 
el.hasAttribute('open')")
+        go_to_path(page, href, wait=False)
 
-        if not is_already_open:
-            logging.info("OpenPGP key card: details is not open, clicking 
summary to open")
-            summary_element.click()
-            try:
-                sync_api.expect(details_element).to_have_attribute("open", "", 
timeout=2000)
-                logging.info("OpenPGP key card: details successfully opened")
-            except Exception as e:
-                logging.warning(
-                    f"OpenPGP key card: failed to confirm details opened after 
clicking summary: {e}, skipping card"
-                )
-                continue
-        else:
-            logging.info("OpenPGP key card: Details already open.")
+        pre_locator = page.locator("pre")
+        sync_api.expect(pre_locator).to_be_visible()
+        key_content = pre_locator.inner_text()
 
-        details_pre_locator = details_element.locator("pre").first
-        try:
-            sync_api.expect(details_pre_locator).to_be_visible(timeout=1000)
-        except Exception as e:
-            logging.warning(
-                f"OpenPGP key card: <pre> tag not visible even after 
attempting to open details: {e}, skipping card"
-            )
-            continue
-
-        key_content = details_pre_locator.inner_text()
         if _OPENPGP_TEST_UID in key_content:
-            fingerprint_locator = 
card.locator('tr:has(th:has-text("Fingerprint")) > td').first
-            fingerprint = fingerprint_locator.inner_text().strip()
-            if fingerprint:
-                logging.info(f"Found test OpenPGP key with fingerprint 
{fingerprint} for deletion")
-                fingerprints_to_delete.append(fingerprint)
-            else:
-                logging.warning("Found test OpenPGP key card but could not 
extract fingerprint")
-        else:
-            logging.debug(f"OpenPGP key card: test UID '{_OPENPGP_TEST_UID}' 
not found in key content")
+            logging.info(f"Found test OpenPGP key with fingerprint 
{fingerprint} for deletion")
+            fingerprints_to_delete.append(fingerprint)
+
+        go_to_path(page, "/keys")
 
     # For the complexity linter only
     test_tidy_up_openpgp_keys_continued(page, fingerprints_to_delete)
@@ -1147,8 +1117,8 @@ def test_tidy_up_openpgp_keys_continued(page: 
sync_api.Page, fingerprints_to_del
     for fingerprint in fingerprints_to_delete:
         logging.info(f"Locating delete form for fingerprint: {fingerprint}")
         # Locate again by fingerprint for robustness
-        card_to_delete_locator = 
page.locator(f'div.card:has(td:has-text("{fingerprint}"))')
-        delete_button_locator = card_to_delete_locator.locator(
+        row_to_delete_locator = 
page.locator(f'tr:has(a[href="/keys/details/{fingerprint}"])')
+        delete_button_locator = row_to_delete_locator.locator(
             'form[action="/keys/delete"] input[type="submit"][value="Delete 
key"]'
         )
 


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to