diff --git a/electionpage/tests.py b/electionpage/tests.py index 1a75a71c..f946bb39 100644 --- a/electionpage/tests.py +++ b/electionpage/tests.py @@ -26,6 +26,7 @@ from selenium.common.exceptions import NoSuchElementException, StaleElementReferenceException from selenium.webdriver.common.by import By from selenium.webdriver.support import expected_conditions as EC +from selenium.webdriver.support.ui import WebDriverWait from common.testUtils import TestHelpers from electionpage.models import ElectionPage, ScrapableElectionPage, SingleSourceElectionPage @@ -195,8 +196,8 @@ def submit_with_num_elections_and_get_error(num, expectReload): self.browser.find_element(By.ID, "submit").click() if expectReload: - self._ensure_eventually_asserts( - lambda: EC.staleness_of(bodyElement)) + # Wait for the navigation: the old page's body goes stale + WebDriverWait(self.browser, timeout=10).until(EC.staleness_of(bodyElement)) try: return self.browser.find_element( diff --git a/static/datatable/src/datatable.ts b/static/datatable/src/datatable.ts index cfae52be..c33ba92a 100644 --- a/static/datatable/src/datatable.ts +++ b/static/datatable/src/datatable.ts @@ -453,8 +453,9 @@ export default class RcvisDataTable { this.toJson(this.table.getData())); } - // Prepare the mock form - const form = document.getElementsByTagName('form')[0]; + // Prepare the mock form: the upload form by id, since the page has other + // forms too (e.g. the logout form in the header) + const form = document.getElementById('form'); const data = $(form).serializeArray(); // AJAX to check if it would survive all serverside processing diff --git a/static/visualizer/theme.css b/static/visualizer/theme.css index d8c0a793..90eeb176 100644 --- a/static/visualizer/theme.css +++ b/static/visualizer/theme.css @@ -264,6 +264,31 @@ h1, h2, h3, h4, h5, h6 { color: var(--rcv-brand); } +.nav-logout-form { + display: inline; + margin: 0; +} + +.nav-logout-button { + padding: 0; + border: 0; + background: none; + font: inherit; + color: var(--rcv-brand); + cursor: pointer; +} + +.nav-logout-button:hover { + color: var(--rcv-brand-deep); + text-decoration: underline; +} + +.nav-logout-button:focus-visible { + outline: 2px solid var(--rcv-brand); + outline-offset: 2px; + border-radius: 3px; +} + /* ------------------------------------------------------------------ */ /* Visualization tab bar (the /v/ page puts its tabs in the header) */ /* ------------------------------------------------------------------ */ diff --git a/templates/visualizer/uploadFile.html b/templates/visualizer/uploadFile.html index 3db0d727..cae30f9e 100644 --- a/templates/visualizer/uploadFile.html +++ b/templates/visualizer/uploadFile.html @@ -6,11 +6,15 @@ {% endblock %} {% block navlinks %} -
{% endblock %} {% block maincontent %}