diff --git a/gratipay/testing/browser.py b/gratipay/testing/browser.py index f62dff3e55..fbcab08803 100644 --- a/gratipay/testing/browser.py +++ b/gratipay/testing/browser.py @@ -113,27 +113,34 @@ def wait_for(self, selector, timeout=2): return element raise NeverShowedUp(selector) - def wait_for_notification(self, type='notice'): - """Wait for a certain ``type`` of notification. Dismiss the - notification and return the message. + def wait_for_notification(self, type='notice', message=None, timeout=2): + """Wait for a certain ``type`` of notification, with a certain message + (if specified). Dismiss the notification and return the message. """ - n_selector = '.notifications-fixed .notification-{}'.format(type) - m_selector = 'span.btn-close' - notification = self.wait_for(n_selector).first - message = notification.find_by_css('div').html - notification.find_by_css(m_selector).first.click() - self.wait_to_disappear(n_selector + ' ' + m_selector) + notification_selector = '.notifications-fixed .notification-{}'.format(type) + close_button_selector = 'span.btn-close' + end_time = time.time() + timeout + while time.time() < end_time: + notification = self.wait_for(notification_selector, timeout).first + candidate = notification.find_by_css('div').html + if message is None or message == candidate: + message = candidate + break + notification.find_by_css(close_button_selector).first.click() + self.wait_to_disappear('#{} {}'.format(notification['id'], close_button_selector)) return message - def wait_for_success(self): - """Wait for a success notification. Dismiss it and return the message. + def wait_for_success(self, message=None): + """Wait for a success notification, with a certain message (if + specified). Dismiss it and return the message. """ - return self.wait_for_notification('success') + return self.wait_for_notification('success', message) - def wait_for_error(self): - """Wait for an error notification. Dismiss it and return the message. + def wait_for_error(self, message=None): + """Wait for an error notification, with a certain message (if + specified). Dismiss it and return the message. """ - return self.wait_for_notification('error') + return self.wait_for_notification('error', message) def __getattr__(self, name): try: diff --git a/js/gratipay/notification.js b/js/gratipay/notification.js index cc74e14f0d..09c257e2e6 100644 --- a/js/gratipay/notification.js +++ b/js/gratipay/notification.js @@ -5,11 +5,22 @@ Gratipay.notification = function(text, type, timeout, closeCallback) { var type = type || 'notice'; var timeout = timeout || (type == 'error' ? 10000 : 5000); + var id = Math.random().toString(36).substring(2, 100); - var dialog = ['div', { 'class': 'notification notification-' + type }, [ 'div', text ]]; + // We want the notification to be fixed at the top of the page even while + // scrolling, without interfering with the heading that's already at the + // top of the page when scrolled the whole way up (logo, sign in, etc.). So + // what we do is create two notification divs. One sits behind and pushes + // the rest of the page content down, so that the header remains visible. + // The other sits in front, and is the one the user actually interacts + // with. It stays at the top of the viewport even while scrolling. + + var placeholder = ['div', {'class': 'notification notification-' + type}, ['div', text]]; + var dialog = ['div', {'class': 'notification notification-' + type, 'id': 'notification-'+id}, + ['div', text]]; var $dialog = $([ - Gratipay.jsonml(dialog), - Gratipay.jsonml(dialog) + Gratipay.jsonml(placeholder), // pushes the whole page down, but not directly seen + Gratipay.jsonml(dialog) // parked at the top even while scrolling ]); // Close if we're on the page the notification links to. diff --git a/requirements.txt b/requirements.txt index f1ecc4593e..5bbcae0225 100644 --- a/requirements.txt +++ b/requirements.txt @@ -39,7 +39,7 @@ ./vendor/Faker-0.7.3.tar.gz ./vendor/six-1.8.0.tar.gz -./vendor/libsass-0.3.0.tar.gz +./vendor/libsass-0.12.3.tar.gz ./vendor/honcho-cfcc7ebb.tar.gz ./vendor/environment-1.0.0.tar.gz diff --git a/vendor/libsass-0.12.3.tar.gz b/vendor/libsass-0.12.3.tar.gz new file mode 100644 index 0000000000..8c6d88c836 Binary files /dev/null and b/vendor/libsass-0.12.3.tar.gz differ diff --git a/vendor/libsass-0.3.0.tar.gz b/vendor/libsass-0.3.0.tar.gz deleted file mode 100644 index e8601ea77d..0000000000 Binary files a/vendor/libsass-0.3.0.tar.gz and /dev/null differ