From 14d211326eb60249c95fbbe0940b5ddebc82cc0e Mon Sep 17 00:00:00 2001 From: Arona Jones Date: Wed, 27 May 2020 18:38:58 -0400 Subject: [PATCH] FIX: CI Locale Issues --- .travis.yml | 3 +++ PyRIGS/settings.py | 1 + PyRIGS/tests/base.py | 4 +++- PyRIGS/tests/regions.py | 20 +++++++++++++++---- RIGS/forms.py | 8 +++++--- .../partials/event_details_form.html | 10 ++++++---- RIGS/tests/test_functional.py | 8 ++++---- assets/tests/test_assets.py | 3 +++ 8 files changed, 41 insertions(+), 16 deletions(-) diff --git a/.travis.yml b/.travis.yml index 5791642b..8f9da399 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,6 +5,9 @@ cache: pip addons: chrome: stable + +before_install: + - export LANGUAGE=en_GB.UTF-8 install: - | diff --git a/PyRIGS/settings.py b/PyRIGS/settings.py index 411569ac..8164b221 100644 --- a/PyRIGS/settings.py +++ b/PyRIGS/settings.py @@ -206,6 +206,7 @@ USE_L10N = True USE_TZ = True +# Need to allow seconds as datetime-local input type spits out a time that has seconds DATETIME_INPUT_FORMATS = ('%Y-%m-%dT%H:%M', '%Y-%m-%dT%H:%M:%S') # Static files (CSS, JavaScript, Images) diff --git a/PyRIGS/tests/base.py b/PyRIGS/tests/base.py index 1b3e12bb..5d0ea81e 100644 --- a/PyRIGS/tests/base.py +++ b/PyRIGS/tests/base.py @@ -24,6 +24,8 @@ def create_browser(): # No caching, please and thank you options.add_argument("--aggressive-cache-discard") options.add_argument("--disk-cache-size=0") + # God Save The Queen + options.add_argument("--lang=en_GB") if os.environ.get('CI', False): options.add_argument("--headless") options.add_argument("--no-sandbox") @@ -58,7 +60,7 @@ def screenshot_failure(func): func(self, *args, **kwargs) except Exception as e: screenshot_name = func.__module__ + "." + func.__qualname__ - screenshot_file = "screenshots/"+func.__qualname__+".png" + screenshot_file = "screenshots/" + func.__qualname__ + ".png" if not pathlib.Path("screenshots").is_dir(): os.mkdir("screenshots") self.driver.save_screenshot(screenshot_file) diff --git a/PyRIGS/tests/regions.py b/PyRIGS/tests/regions.py index 74e20787..a4ac9253 100644 --- a/PyRIGS/tests/regions.py +++ b/PyRIGS/tests/regions.py @@ -1,4 +1,5 @@ from pypom import Region +from django.utils import timezone from selenium.webdriver.common.by import By from selenium.webdriver.support import expected_conditions from selenium.webdriver.remote.webelement import WebElement @@ -17,6 +18,17 @@ def parse_bool_from_string(string): else: return False +# 12-Hour vs 24-Hour Time. Affects widget display + + +def get_time_format(): + # Default + time_format = "%H:%M" + # If system is 12hr + if timezone.now().strftime("%p"): + time_format = "%I:%M %p" + return time_format + class BootstrapSelectElement(Region): _main_button_locator = (By.CSS_SELECTOR, 'button.dropdown-toggle') @@ -127,23 +139,23 @@ class DatePicker(Region): class TimePicker(Region): @property def value(self): - return datetime.datetime.strptime(self.root.get_attribute("value"), "%H:%M") + return datetime.datetime.strptime(self.root.get_attribute("value"), get_time_format()) def set_value(self, value): self.root.clear() - self.root.send_keys(value.strftime("%H:%M")) + self.root.send_keys(value.strftime(get_time_format())) class DateTimePicker(Region): @property def value(self): - return datetime.datetime.strptime(self.root.get_attribute("value"), "%Y-%m-%d %H:%M") + return datetime.datetime.strptime(self.root.get_attribute("value"), "%Y-%m-%d " + get_time_format()) def set_value(self, value): self.root.clear() date = value.date().strftime("%d%m%Y") - time = value.time().strftime("%H%M") + time = value.time().strftime(get_time_format()) self.root.send_keys(date) self.root.send_keys(Keys.TAB) diff --git a/RIGS/forms.py b/RIGS/forms.py index 07d59bb1..934ef76c 100644 --- a/RIGS/forms.py +++ b/RIGS/forms.py @@ -13,13 +13,15 @@ from RIGS import models # Override the django form defaults to use the HTML date/time/datetime UI elements forms.DateField.widget = forms.DateInput(attrs={'type': 'date'}) -forms.TimeField.widget = forms.TextInput(attrs={'type': 'time'}) -forms.DateTimeField.widget = forms.DateTimeInput(attrs={'type': 'datetime-local'}) +forms.TimeField.widget = forms.TimeInput(attrs={'type': 'time'}, format='%H:%M') +forms.DateTimeField.widget = forms.DateTimeInput(attrs={'type': 'datetime-local'}, format='%Y-%m-%d %H:%M') # Events Shit + + class EventForm(forms.ModelForm): - datetime_input_formats = formats.get_format_lazy("DATETIME_INPUT_FORMATS") + list(settings.DATETIME_INPUT_FORMATS) + datetime_input_formats = list(settings.DATETIME_INPUT_FORMATS) meet_at = forms.DateTimeField(input_formats=datetime_input_formats, required=False) access_at = forms.DateTimeField(input_formats=datetime_input_formats, required=False) diff --git a/RIGS/templates/partials/event_details_form.html b/RIGS/templates/partials/event_details_form.html index 850c9532..a1ca202b 100644 --- a/RIGS/templates/partials/event_details_form.html +++ b/RIGS/templates/partials/event_details_form.html @@ -1,4 +1,6 @@ {% load widget_tweaks %} +{% load l10n %} +
Event Details
@@ -49,7 +51,7 @@ {% render_field form.start_date class+="form-control" %}
- {% render_field form.start_time class+="form-control" %} + {% render_field form.start_time class+="form-control" step="60" %}
@@ -64,7 +66,7 @@ {% render_field form.end_date class+="form-control" %}
- {% render_field form.end_time class+="form-control" %} + {% render_field form.end_time class+="form-control" step="60" %}
@@ -77,7 +79,7 @@ class="col-sm-4 control-label">{{ form.access_at.label }}
- {% render_field form.access_at class+="form-control" %} + {% render_field form.access_at class+="form-control" step="60" %}
@@ -85,7 +87,7 @@ class="col-sm-4 control-label">{{ form.meet_at.label }}
- {% render_field form.meet_at class+="form-control" %} + {% render_field form.meet_at class+="form-control" step="60" %}
diff --git a/RIGS/tests/test_functional.py b/RIGS/tests/test_functional.py index f9d442ae..c1094bda 100644 --- a/RIGS/tests/test_functional.py +++ b/RIGS/tests/test_functional.py @@ -119,7 +119,7 @@ class TestEventCreate(BaseRigboardTest): self.page.name = "Test Rig" self.page.start_date = datetime.date(2015, 1, 1) - self.page.start_time = datetime.time(10) + self.page.start_time = datetime.time(10, 00) self.page.end_date = datetime.date(2015, 1, 10) self.page.access_at = datetime.datetime(2015, 1, 1, 9) self.page.dry_hire = True @@ -210,8 +210,8 @@ class TestEventCreate(BaseRigboardTest): self.page.name = "Test Date Validation" # end time before start self.page.start_date = datetime.date(2020, 1, 1) - self.page.start_time = datetime.time(10) - self.page.end_time = datetime.time(9) + self.page.start_time = datetime.time(10, 00) + self.page.end_time = datetime.time(9, 00) # Expected to fail self.page.submit() @@ -219,7 +219,7 @@ class TestEventCreate(BaseRigboardTest): self.assertIn("can't finish before it has started", self.page.errors["General form errors"][0]) # Fix it - self.page.end_time = datetime.time(23) + self.page.end_time = datetime.time(23, 00) # Should work self.page.submit() diff --git a/assets/tests/test_assets.py b/assets/tests/test_assets.py index a6dab513..0e12a6f2 100644 --- a/assets/tests/test_assets.py +++ b/assets/tests/test_assets.py @@ -16,6 +16,7 @@ from selenium.webdriver.support.ui import WebDriverWait from PyRIGS.tests.base import animation_is_finished import datetime from django.utils import timezone +from selenium.webdriver.common.action_chains import ActionChains @screenshot_failure_cls @@ -134,6 +135,8 @@ class TestAssetForm(AutoLoginTest): self.page.purchased_from_selector.set_option(self.supplier.name, True) self.page.purchase_price = "12.99" self.page.salvage_value = "99.12" + # FIXME Scroll down to make failure screenshot more useful... + ActionChains(self.driver).move_to_element(self.driver.find_element_by_class_name('btn-success')).perform() self.page.date_acquired = acquired = datetime.date(2020, 5, 20) self.page.parent_selector.toggle()