Merged in [18884] from jennifer@painless-security.com:

Move agenda TZ selector out of sidebar so it is always available. Fixes #3172.
 - Legacy-Id: 18885
Note: SVN reference [18884] has been migrated to Git commit 4a287d665d
This commit is contained in:
Robert Sparks 2021-03-03 18:55:19 +00:00
commit ae67fc0af2
4 changed files with 153 additions and 13 deletions

View file

@ -41,7 +41,7 @@ try:
from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support.ui import Select, WebDriverWait
from selenium.webdriver.support import expected_conditions
from selenium.common.exceptions import NoSuchElementException
except ImportError as e:
@ -904,6 +904,107 @@ class AgendaTests(MeetingTestCase):
with self.assertRaises(NoSuchElementException):
self.driver.find_element_by_xpath('//a[text()="%s"]' % slide.title)
def _wait_for_tz_change_from(self, old_tz):
"""Helper to wait for tz displays to change from their old value"""
match = 'text()!="%s"' % old_tz
WebDriverWait(self.driver, 2).until(
expected_conditions.presence_of_element_located((By.XPATH, '//*[@class="current-tz"][%s]' % match))
)
def test_agenda_time_zone_selection(self):
self.assertNotEqual(self.meeting.time_zone, 'UTC', 'Meeting time zone must not be UTC')
self.driver.get(self.absreverse('ietf.meeting.views.agenda'))
# wait for the select box to be updated - look for an arbitrary time zone to be in
# its options list to detect this
WebDriverWait(self.driver, 2).until(
expected_conditions.presence_of_element_located((By.XPATH, '//option[@value="America/Halifax"]'))
)
tz_select_input = Select(self.driver.find_element_by_id('timezone_select'))
meeting_tz_link = self.driver.find_element_by_id('meeting-timezone')
local_tz_link = self.driver.find_element_by_id('local-timezone')
utc_tz_link = self.driver.find_element_by_id('utc-timezone')
tz_displays = self.driver.find_elements_by_css_selector('.current-tz')
self.assertGreaterEqual(len(tz_displays), 1)
# we'll check that all current-tz elements are updated, but first check that at least one is in the nav sidebar
self.assertIsNotNone(self.driver.find_element_by_css_selector('.nav .current-tz'))
# Moment.js guesses local time zone based on the behavior of Selenium's web client. This seems
# to inherit Django's settings.TIME_ZONE but I don't know whether that's guaranteed to be consistent.
# To avoid test fragility, ask Moment what it considers local and expect that.
local_tz = self.driver.execute_script('return moment.tz.guess();')
self.assertNotEqual(self.meeting.time_zone, local_tz, 'Meeting time zone must not be local time zone')
self.assertNotEqual(local_tz, 'UTC', 'Local time zone must not be UTC')
# Should start off in meeting time zone
self.assertEqual(tz_select_input.first_selected_option.get_attribute('value'), self.meeting.time_zone)
for disp in tz_displays:
self.assertEqual(disp.text.strip(), self.meeting.time_zone)
# Click 'local' button
local_tz_link.click()
self._wait_for_tz_change_from(self.meeting.time_zone)
self.assertEqual(tz_select_input.first_selected_option.get_attribute('value'), local_tz)
for disp in tz_displays:
self.assertEqual(disp.text.strip(), local_tz)
# click 'utc' button
utc_tz_link.click()
self._wait_for_tz_change_from(local_tz)
self.assertEqual(tz_select_input.first_selected_option.get_attribute('value'), 'UTC')
for disp in tz_displays:
self.assertEqual(disp.text.strip(), 'UTC')
# click back to meeting
meeting_tz_link.click()
self._wait_for_tz_change_from('UTC')
self.assertEqual(tz_select_input.first_selected_option.get_attribute('value'), self.meeting.time_zone)
for disp in tz_displays:
self.assertEqual(disp.text.strip(), self.meeting.time_zone)
# and then back to UTC...
utc_tz_link.click()
self._wait_for_tz_change_from(self.meeting.time_zone)
self.assertEqual(tz_select_input.first_selected_option.get_attribute('value'), 'UTC')
for disp in tz_displays:
self.assertEqual(disp.text.strip(), 'UTC')
# ... and test the switch from UTC to local
local_tz_link.click()
self._wait_for_tz_change_from('UTC')
self.assertEqual(tz_select_input.first_selected_option.get_attribute('value'), local_tz)
for disp in tz_displays:
self.assertEqual(disp.text.strip(), local_tz)
# Now select a different item from the select input
tz_select_input.select_by_value('America/Halifax')
self._wait_for_tz_change_from(self.meeting.time_zone)
self.assertEqual(tz_select_input.first_selected_option.get_attribute('value'), 'America/Halifax')
for disp in tz_displays:
self.assertEqual(disp.text.strip(), 'America/Halifax')
def test_agenda_time_zone_selection_updates_weekview(self):
"""Changing the time zone should update the weekview to match"""
# enable a filter so the weekview iframe is visible
self.driver.get(self.absreverse('ietf.meeting.views.agenda') + '?show=mars')
# wait for the select box to be updated - look for an arbitrary time zone to be in
# its options list to detect this
WebDriverWait(self.driver, 2).until(
expected_conditions.presence_of_element_located((By.XPATH, '//option[@value="America/Halifax"]'))
)
tz_select_input = Select(self.driver.find_element_by_id('timezone_select'))
# Now select a different item from the select input
tz_select_input.select_by_value('America/Halifax')
self._wait_for_tz_change_from(self.meeting.time_zone)
self.assertEqual(tz_select_input.first_selected_option.get_attribute('value'), 'America/Halifax')
self.driver.switch_to.frame('weekview')
wv_url = self.driver.execute_script('return document.location.href')
self.assertIn('tz=america/halifax', wv_url)
@skipIf(skip_selenium, skip_message)
class WeekviewTests(MeetingTestCase):

View file

@ -143,6 +143,10 @@ class MeetingTests(TestCase):
self.assertIn(session.group.parent.acronym.upper(), agenda_content)
self.assertIn(slot.location.name, agenda_content)
self.assertIn(time_interval, agenda_content)
self.assertIsNotNone(q(':input[value="%s"]' % meeting.time_zone),
'Time zone selector should show meeting timezone')
self.assertIsNotNone(q('.nav *:contains("%s")' % meeting.time_zone),
'Time zone indicator should be in nav sidebar')
# plain
time_interval = "%s-%s" % (slot.time.strftime("%H:%M").lstrip("0"), (slot.time + slot.duration).strftime("%H:%M").lstrip("0"))

View file

@ -28,8 +28,9 @@ function timezone_init(current) {
var tz_names = moment.tz.names();
var select = $('#timezone_select');
select.empty();
$.each(tz_names, function(i, item) {
if (current == item) {
if (current === item) {
select.append($('<option/>', {
selected: "selected", html: item, value: item }));
} else {
@ -178,7 +179,7 @@ function add_tooltips() {
// Update times on the agenda based on the selected timezone
function update_times(newtz) {
current_timezone = newtz;
$('#title-timezone').html(newtz);
$('span.current-tz').html(newtz);
$('span.time').each(function () {
if (this.format == 4) {
var tz = this.start_ts.tz(newtz).format(" z");

View file

@ -28,6 +28,27 @@
.session-materials .agenda-frame,.minutes-frame {
white-space: normal;
}
div.tz-display {
margin-bottom: 0.5em;
margin-top: 1em;
text-align: right;
}
.tz-display a {
cursor: pointer;
}
.tz-display label {
font-weight: normal;
}
.tz-display select {
min-width: 15em;
}
#affix .nav li.tz-display {
padding: 4px 20px;
}
#affix .nav li.tz-display a {
display: inline;
padding: 0;
}
{% endblock %}
{% block bodyAttrs %}data-spy="scroll" data-target="#affix"{% endblock %}
@ -50,8 +71,23 @@
{# cache this part -- it takes 3-6 seconds to generate #}
{% load cache %}
{% cache cache_time ietf_meeting_agenda_utc schedule.meeting.number request.path %}
<h1>Agenda <small id="title-timezone" class="pull-right" >{{timezone}}</small></h1>
<div class="row">
<div class="col-xs-6"><h1>Agenda</h1></div>
<div class="col-xs-6">
<div class="tz-display">
<div><small>
<label for="timezone_select">Time zone:</label>
<a id="meeting-timezone" onclick="use_timezone(0)">Meeting</a> |
<a id="local-timezone" onclick="use_timezone(1)">Local</a> |
<a id="utc-timezone" onclick="use_timezone(2)">UTC</a>
</small></div>
<select id="timezone_select">
{# Avoid blank while loading. JavaScript replaces the option list after init. #}
<option selected>{{ timezone }}</option>
</select>
</div>
</div>
</div>
{% if is_current_meeting %}
<p class="alert alert-info">
<b>Note:</b> IETF agendas are subject to change, up to and during a meeting.
@ -319,15 +355,13 @@
{% endifchanged %}
{% endfor %}
<li><hr/></li>
<li class="tzselect">Select timezone:</li>
<li><a id="meeting-timezone" onclick="use_timezone(0)">Meeting Timezone</a></li>
<li><a id="local-timezone" onclick="use_timezone(1)">Local Timezone</a></li>
<li><a id="utc-timezone" onclick="use_timezone(2)">UTC</a></li>
<li id="timezone">
<select style="width: 12em;" id="timezone_select"></select>
<li class="tz-display">Showing <span class="current-tz">{{ timezone }}</span> time</li>
<li class="tz-display"><span> {# span avoids applying nav link styling to these shortcuts #}
<a onclick="use_timezone(0)">Meeting time</a> |
<a onclick="use_timezone(1)">Local time</a> |
<a onclick="use_timezone(2)">UTC</a></span>
</li>
{% if settings.DEBUG and settings.DEBUG_AGENDA %}
{% if settings.DEBUG and settings.DEBUG_AGENDA %}
<li><hr/></li>
<li><span id="current-time"></span></li>
{% endif %}