diff --git a/conftest.py b/conftest.py
index 53d55d7..a75404e 100644
--- a/conftest.py
+++ b/conftest.py
@@ -58,9 +58,15 @@ def webapp():
def make_webapp_url( endpoint, **kwargs ):
"""Generate a webapp URL."""
with app.test_request_context():
+ # NOTE: When we perform actions at high speed, the notification balloons can build up
+ # very quickly, causing problems by obscuring other elements and making them non-clickable :-/
+ # We used to explicitly dismiss them, but it's simpler to just always disable them.
+ kwargs["store_msgs"] = 1
+ # check if the tests are being run headless
if pytest.config.option.headless: #pylint: disable=no-member
- # headless browsers have no clipboard support :-/
+ # yup - there is no clipboard support :-/
pytest.config.option.no_clipboard = True #pylint: disable=no-member
+ # check if we should disable using the clipboard for snippets
if pytest.config.option.no_clipboard: #pylint: disable=no-member
# NOTE: It's not a bad idea to bypass the clipboard, even when running in a browser,
# to avoid problems if something else uses the clipboard while the tests are running.
diff --git a/vasl_templates/webapp/static/snippets.js b/vasl_templates/webapp/static/snippets.js
index fcc7e7c..b1aae29 100644
--- a/vasl_templates/webapp/static/snippets.js
+++ b/vasl_templates/webapp/static/snippets.js
@@ -20,11 +20,6 @@ var gDefaultScenario = null ;
function generate_snippet( $btn, extra_params )
{
- // initialize
- storeMsgForTestSuite( "_last-info_", "" ) ;
- storeMsgForTestSuite( "_last-warning_", "" ) ;
- storeMsgForTestSuite( "_last-error_", "" ) ;
-
// extract the scenario date components
var params = {} ;
var scenario_date = $("input[name='SCENARIO_DATE']").datepicker( "getDate" ) ;
diff --git a/vasl_templates/webapp/static/utils.js b/vasl_templates/webapp/static/utils.js
index 0f2e7de..e3df78e 100644
--- a/vasl_templates/webapp/static/utils.js
+++ b/vasl_templates/webapp/static/utils.js
@@ -146,62 +146,26 @@ function ask( title, msg, args )
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-function showInfoMsg( msg )
-{
- // show the informational message
- $.growl( {
- style: "notice",
- title: null,
- message: msg,
- location: "br",
- } ) ;
- storeMsgForTestSuite( "_last-info_", msg ) ;
-}
+function showInfoMsg( msg ) { doShowNotificationMsg( "info", msg ) ; }
+function showWarningMsg( msg ) { doShowNotificationMsg( "warning", msg ) ; }
+function showErrorMsg( msg ) { doShowNotificationMsg( "error", msg ) ; }
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-function showWarningMsg( msg )
+function doShowNotificationMsg( msg_type, msg )
{
- // show the warning message
- $.growl( {
- style: "warning",
- title: null,
- message: msg,
- location: "br",
- } ) ;
- storeMsgForTestSuite( "_last-warning_", msg ) ;
-}
-
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+ if ( getUrlParam( "store_msgs" ) ) {
+ // store the message for the test suite
+ $( "#_last-" + msg_type + "_" ).val( msg ) ;
+ return ;
+ }
-function showErrorMsg( msg )
-{
- // show the error message
+ // show the notification message
$.growl( {
- style: "error",
+ style: (msg_type === "info") ? "notice" : msg_type,
title: null,
message: msg,
location: "br",
- fixed: true,
+ fixed: (msg_type == "error"),
} ) ;
- storeMsgForTestSuite( "_last-error_", msg ) ;
-}
-
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-function storeMsgForTestSuite( id, msg )
-{
- // store a message for the test suite
- if ( ! getUrlParam( "store_msgs" ) )
- return ;
- var $elem = $( "#"+id ) ;
- if ( $elem.length === 0 ) {
- // NOTE: The
we store the message in must be visible, otherwise
- // Selenium doesn't return any text for it :-/
- $elem = $( "
" ) ;
- $("body").append( $elem ) ;
- }
- $elem.html( msg ) ;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
diff --git a/vasl_templates/webapp/templates/index.html b/vasl_templates/webapp/templates/index.html
index 444c68a..c04424e 100644
--- a/vasl_templates/webapp/templates/index.html
+++ b/vasl_templates/webapp/templates/index.html
@@ -24,6 +24,10 @@
+
+
+
+
diff --git a/vasl_templates/webapp/tests/test_ob.py b/vasl_templates/webapp/tests/test_ob.py
index 6771697..d25f7a1 100644
--- a/vasl_templates/webapp/tests/test_ob.py
+++ b/vasl_templates/webapp/tests/test_ob.py
@@ -6,7 +6,7 @@ import types
from selenium.webdriver.support.ui import Select
from vasl_templates.webapp.tests.utils import \
- get_nationalities, get_clipboard, get_stored_msg, select_tab, find_child, find_children, \
+ get_nationalities, get_clipboard, get_stored_msg, set_stored_msg_marker, select_tab, find_child, find_children, \
add_simple_note, edit_simple_note, get_sortable_entry_count, drag_sortable_entry_to_trash, \
select_droplist_val
@@ -92,7 +92,7 @@ def test_nationality_specific( webapp, webdriver ): #pylint: disable=too-many-lo
"""Check that nationality-specific buttons are shown/hidden correctly."""
# initialize
- webdriver.get( webapp.url_for( "main", store_msgs=1 ) )
+ webdriver.get( webapp.url_for( "main" ) )
nationalities = get_nationalities( webapp )
# initialize
@@ -108,16 +108,17 @@ def test_nationality_specific( webapp, webdriver ): #pylint: disable=too-many-lo
# test snippet generation
set_scenario_date( date )
select_tab( "ob1" )
+ marker = set_stored_msg_marker( "_last-warning_" )
btn.click()
assert get_clipboard() == expected
# check if a warning was issued
- last_warning = get_stored_msg( "_last-warning_" ) or ""
+ last_warning = get_stored_msg( "_last-warning_" )
image_url = find_child( "img", btn ).get_attribute( "src" )
if warning:
assert "are only available" in last_warning
assert "snippet-disabled.png" in image_url
else:
- assert last_warning == ""
+ assert last_warning == marker
assert "snippet.png" in image_url
# initialize
diff --git a/vasl_templates/webapp/tests/test_scenario_persistence.py b/vasl_templates/webapp/tests/test_scenario_persistence.py
index c9145d7..225c592 100644
--- a/vasl_templates/webapp/tests/test_scenario_persistence.py
+++ b/vasl_templates/webapp/tests/test_scenario_persistence.py
@@ -6,7 +6,7 @@ from selenium.webdriver.support.ui import Select
from vasl_templates.webapp.tests.utils import \
get_nationalities, set_template_params, select_tab, select_menu_option, get_sortable_entry_text, \
- get_stored_msg, set_stored_msg, find_child, find_children
+ get_stored_msg, set_stored_msg, set_stored_msg_marker, find_child, find_children
# ---------------------------------------------------------------------
@@ -158,7 +158,7 @@ def test_unknown_vo( webapp, webdriver ):
"""Test detection of unknown vehicles/ordnance."""
# initialize
- webdriver.get( webapp.url_for( "main", scenario_persistence=1, store_msgs=1 ) )
+ webdriver.get( webapp.url_for( "main", scenario_persistence=1 ) )
_ = _save_scenario() # nb: force the "scenario-persistence" element to be created
# load a scenario that has unknown vehicles/ordnance
@@ -170,6 +170,7 @@ def test_unknown_vo( webapp, webdriver ):
"VEHICLES_2": [ "unknown vehicle 2" ],
"ORDNANCE_2": [ "unknown ordnance 2" ],
}
+ _ = set_stored_msg_marker( "_last-warning_" )
_load_scenario( scenario_params )
last_warning = get_stored_msg( "_last-warning_" )
assert last_warning.startswith( "Unknown vehicles/ordnance:" )
diff --git a/vasl_templates/webapp/tests/test_snippets.py b/vasl_templates/webapp/tests/test_snippets.py
index 28da9fb..8c3b2d3 100644
--- a/vasl_templates/webapp/tests/test_snippets.py
+++ b/vasl_templates/webapp/tests/test_snippets.py
@@ -2,9 +2,9 @@
from selenium.webdriver.common.keys import Keys
-from vasl_templates.webapp.tests.utils import select_tab, set_template_params, get_clipboard
from vasl_templates.webapp.tests.utils import \
- wait_for_page_ready, get_stored_msg, dismiss_notifications, find_child, \
+ select_tab, set_template_params, get_clipboard, \
+ wait_for_page_ready, get_stored_msg, set_stored_msg_marker, find_child, \
for_each_template, add_simple_note, edit_simple_note, \
get_sortable_entry_count, generate_sortable_entry_snippet, drag_sortable_entry_to_trash
@@ -14,7 +14,7 @@ def test_scenario_snippets( webapp, webdriver ):
"""Test HTML snippet generation."""
# initialize
- webdriver.get( webapp.url_for( "main", store_msgs=1 ) )
+ webdriver.get( webapp.url_for( "main" ) )
select_tab( "scenario" )
btn = find_child( "button.generate[data-id='scenario']" )
@@ -65,7 +65,7 @@ def test_vc_snippets( webapp, webdriver ):
"""Test HTML snippet generation."""
# initialize
- webdriver.get( webapp.url_for( "main", store_msgs=1 ) )
+ webdriver.get( webapp.url_for( "main" ) )
select_tab( "scenario" )
btn = find_child( "button.generate[data-id='victory_conditions']" )
@@ -100,7 +100,7 @@ def test_scenario_notes_snippets( webapp, webdriver ):
"""Test HTML snippet generation."""
# initialize
- webdriver.get( webapp.url_for( "main", store_msgs=1 ) )
+ webdriver.get( webapp.url_for( "main" ) )
select_tab( "scenario" )
# add some scenario notes and check their snippets
@@ -125,7 +125,7 @@ def test_players_snippets( webapp, webdriver ):
"""Test HTML snippet generation."""
# initialize
- webdriver.get( webapp.url_for( "main", store_msgs=1 ) )
+ webdriver.get( webapp.url_for( "main" ) )
select_tab( "scenario" )
btn = find_child( "button.generate[data-id='players']" )
@@ -183,7 +183,6 @@ def test_edit_templates( webapp, webdriver ):
webdriver.execute_script( "$(arguments[0]).click();", elem )
edit_template( orig_template_id )
# check that the new template is being used
- dismiss_notifications()
elem = find_child( "button.generate[data-id='{}']".format( orig_template_id ) )
elem.click()
assert get_clipboard() == "EDITED TEMPLATE: {}".format( orig_template_id )
@@ -239,6 +238,7 @@ def _test_snippet( btn, params, expected, expected2 ):
# set the template parameters and generate the snippet
set_template_params( params )
+ marker = set_stored_msg_marker( "_last-warning_" )
btn.click()
snippet = get_clipboard()
lines = [ l.strip() for l in snippet.split("\n") ]
@@ -246,7 +246,7 @@ def _test_snippet( btn, params, expected, expected2 ):
assert snippet == expected
# check warnings for mandatory parameters
- last_warning = get_stored_msg( "_last-warning_" ) or ""
+ last_warning = get_stored_msg( "_last-warning_" )
if isinstance( expected2, list):
# check for mandatory parameters
param_names = [ "scenario name", "scenario location", "scenario date" ]
@@ -261,4 +261,4 @@ def _test_snippet( btn, params, expected, expected2 ):
else:
# make sure there was no warning message
assert expected2 is None
- assert not last_warning
+ assert last_warning == marker
diff --git a/vasl_templates/webapp/tests/test_ssr.py b/vasl_templates/webapp/tests/test_ssr.py
index c18fd56..97e4806 100644
--- a/vasl_templates/webapp/tests/test_ssr.py
+++ b/vasl_templates/webapp/tests/test_ssr.py
@@ -3,7 +3,7 @@
import html
from vasl_templates.webapp.tests.utils import \
- select_tab, find_child, get_clipboard, dismiss_notifications, \
+ select_tab, find_child, get_clipboard, \
add_simple_note, edit_simple_note, drag_sortable_entry_to_trash, get_sortable_entry_count
# ---------------------------------------------------------------------
@@ -36,7 +36,6 @@ def test_ssr( webapp, webdriver ):
if width:
val += "\nwidth = [{}]".format( width )
assert html.unescape( get_clipboard() ) == val
- dismiss_notifications()
# add an SSR and generate the SSR snippet
add_ssr( "This is my first SSR." )
diff --git a/vasl_templates/webapp/tests/test_template_packs.py b/vasl_templates/webapp/tests/test_template_packs.py
index 8b65631..6508eb7 100644
--- a/vasl_templates/webapp/tests/test_template_packs.py
+++ b/vasl_templates/webapp/tests/test_template_packs.py
@@ -9,9 +9,8 @@ from selenium.webdriver.support.ui import Select
from vasl_templates.webapp import snippets
from vasl_templates.webapp.tests.utils import \
- select_tab, select_menu_option, dismiss_notifications, get_clipboard, \
- get_stored_msg, set_stored_msg, add_simple_note, for_each_template, find_child, find_children, \
- select_droplist_val, get_droplist_vals
+ select_tab, select_menu_option, get_clipboard, get_stored_msg, set_stored_msg, set_stored_msg_marker,\
+ add_simple_note, for_each_template, find_child, find_children, select_droplist_val, get_droplist_vals
# ---------------------------------------------------------------------
@@ -19,13 +18,12 @@ def test_individual_files( webapp, webdriver ):
"""Test loading individual template files."""
# initialize
- webdriver.get( webapp.url_for( "main", store_msgs=1, template_pack_persistence=1 ) )
+ webdriver.get( webapp.url_for( "main", template_pack_persistence=1 ) )
# try uploading a customized version of each template
def test_template( template_id, orig_template_id ):
"""Test uploading a customized version of the template."""
# make sure generating a snippet returns something
- dismiss_notifications()
elem, clipboard = _generate_snippet( template_id, orig_template_id )
assert clipboard != ""
# upload a new template
@@ -35,7 +33,6 @@ def test_individual_files( webapp, webdriver ):
)
select_menu_option( "template_pack" )
# make sure generating a snippet returns the new version
- dismiss_notifications()
elem.click()
assert get_clipboard() == "UPLOADED TEMPLATE"
for_each_template( test_template )
@@ -44,16 +41,18 @@ def test_individual_files( webapp, webdriver ):
set_stored_msg( "_template_pack_persistence_",
"filename.xyz | UPLOADED TEMPLATE"
)
+ _ = set_stored_msg_marker( "_last-error_" )
select_menu_option( "template_pack" )
- last_error_msg = get_stored_msg("_last-error_" )
+ last_error_msg = get_stored_msg( "_last-error_" )
assert "Invalid template extension" in last_error_msg
# try uploading a template with an unknown filename
set_stored_msg( "_template_pack_persistence_",
"unknown.j2 | UPLOADED TEMPLATE"
)
+ _ = set_stored_msg_marker( "_last-error_" )
select_menu_option( "template_pack" )
- last_error_msg = get_stored_msg("_last-error_" )
+ last_error_msg = get_stored_msg( "_last-error_" )
assert "Invalid template filename" in last_error_msg
# ---------------------------------------------------------------------
@@ -62,23 +61,26 @@ def test_zip_files( webapp, webdriver ):
"""Test loading ZIP'ed template packs."""
# initialize
- webdriver.get( webapp.url_for( "main", store_msgs=1, template_pack_persistence=1 ) )
+ webdriver.get( webapp.url_for( "main", template_pack_persistence=1 ) )
# upload a template pack that contains a full set of templates
zip_data = _make_zip_from_files( "full" )
+ marker = set_stored_msg_marker( "_last-error_" )
_upload_template_pack( zip_data )
- assert get_stored_msg("_last-error_") is None
+ assert get_stored_msg( "_last-error_" ) == marker
# check that the uploaded templates are being used
_check_snippets( lambda tid: "Customized {}.".format( tid.upper() ) )
# upload only part of template pack
+ _ = set_stored_msg_marker( "_last-error_" )
_upload_template_pack( zip_data[ : int(len(zip_data)/2) ] )
- assert get_stored_msg("_last-error_").startswith( "Can't unpack the ZIP:" )
+ assert get_stored_msg( "_last-error_" ).startswith( "Can't unpack the ZIP:" )
# try uploading an empty template pack
+ _ = set_stored_msg_marker( "_last-error_" )
_upload_template_pack( b"" )
- assert get_stored_msg("_last-error_").startswith( "Can't unpack the ZIP:" )
+ assert get_stored_msg( "_last-error_" ).startswith( "Can't unpack the ZIP:" )
# NOTE: We can't test the limit on template pack size, since it happens after the browser's
# "open file" dialog has finished, but before we read the file data (i.e. we don't execute
@@ -105,7 +107,7 @@ def test_nationality_data( webapp, webdriver ):
"""Test a template pack with nationality data."""
# initialize
- webdriver.get( webapp.url_for( "main", store_msgs=1, template_pack_persistence=1 ) )
+ webdriver.get( webapp.url_for( "main", template_pack_persistence=1 ) )
select_tab( "scenario" )
# select the British as player 1
@@ -122,8 +124,9 @@ def test_nationality_data( webapp, webdriver ):
# upload a template pack that contains nationality data
zip_data = _make_zip_from_files( "with-nationality-data" )
+ marker = set_stored_msg_marker( "_last-error_" )
_upload_template_pack( zip_data )
- assert get_stored_msg("_last-error_") is None
+ assert get_stored_msg( "_last-error_" ) == marker
# check that the UI was updated correctly
assert tab_ob1.text.strip() == "Poms! OB"
@@ -170,7 +173,6 @@ def _check_snippets( expected ):
def test_template( template_id, orig_template_id ):
"""Test each template."""
- dismiss_notifications()
_, clipboard = _generate_snippet( template_id, orig_template_id )
assert clipboard == expected( template_id )
for_each_template( test_template )
diff --git a/vasl_templates/webapp/tests/test_vehicles_ordnance.py b/vasl_templates/webapp/tests/test_vehicles_ordnance.py
index 3d5a6ee..5a08742 100644
--- a/vasl_templates/webapp/tests/test_vehicles_ordnance.py
+++ b/vasl_templates/webapp/tests/test_vehicles_ordnance.py
@@ -7,7 +7,7 @@ from selenium.webdriver.common.action_chains import ActionChains
from vasl_templates.webapp.tests.utils import \
wait_for_page_ready, select_tab, set_template_params, find_child, find_children, \
- get_clipboard, click_dialog_button, dismiss_notifications
+ get_clipboard, click_dialog_button
# ---------------------------------------------------------------------
@@ -64,7 +64,6 @@ def test_crud( webapp, webdriver ):
"""Check the generated vehicle/ordnance snippet."""
# check the snippet
select_tab( "ob{}".format( player_no ) )
- dismiss_notifications()
btn = find_child( "button[data-id='{}_{}']".format( vo_type, player_no ) )
btn.click()
buf = get_clipboard()
@@ -135,7 +134,6 @@ def test_snippets( webapp, webdriver ):
vo_type0 = vo_type[:-1] if vo_type.endswith("s") else vo_type
# test a full example
add_vo( vo_type, 1, "a german {}".format(vo_type) )
- dismiss_notifications()
btn = find_child( "button[data-id='{}_1']".format( vo_type ) )
btn.click()
expected = [
@@ -152,7 +150,6 @@ def test_snippets( webapp, webdriver ):
# test a partial example
add_vo( vo_type, 1, "another german {}".format(vo_type) )
- dismiss_notifications()
btn = find_child( "button[data-id='{}_1']".format( vo_type ) )
btn.click()
expected = [
@@ -168,7 +165,6 @@ def test_snippets( webapp, webdriver ):
# test a minimal example
add_vo( vo_type, 1, "name only" )
- dismiss_notifications()
btn = find_child( "button[data-id='{}_1']".format( vo_type ) )
btn.click()
assert get_clipboard() == \
@@ -194,7 +190,6 @@ def test_variable_capabilities( webapp, webdriver ):
vehicles2 = find_child( "button.generate[data-id='vehicles_2']" )
def do_test( month, year, expected ):
"""Set the date and check the vehicle snippet."""
- dismiss_notifications()
select_tab( "scenario" )
set_template_params( { "SCENARIO_DATE": "{:02d}/01/{}".format(month,year) } )
select_tab( "ob2" )
diff --git a/vasl_templates/webapp/tests/utils.py b/vasl_templates/webapp/tests/utils.py
index 2827129..c6cfab0 100644
--- a/vasl_templates/webapp/tests/utils.py
+++ b/vasl_templates/webapp/tests/utils.py
@@ -5,6 +5,7 @@ import urllib.request
import json
import time
import re
+import uuid
import pytest
from PyQt5.QtWidgets import QApplication
@@ -233,22 +234,24 @@ def find_sortable_helper( sortable, tag ):
# ---------------------------------------------------------------------
-def get_stored_msg( msg_id ):
+def get_stored_msg( msg_type ):
"""Get a message stored for us by the front-end."""
- elem = find_child( "#"+msg_id )
- if not elem:
- return None
- if elem.tag_name == "div":
- return elem.text
+ elem = find_child( "#" + msg_type )
assert elem.tag_name == "textarea"
return elem.get_attribute( "value" )
-def set_stored_msg( msg_id, val ):
+def set_stored_msg( msg_type, val ):
"""Set a message for the front-end."""
- elem = find_child( "#"+msg_id )
+ elem = find_child( "#" + msg_type )
assert elem.tag_name == "textarea"
_webdriver.execute_script( "arguments[0].value = arguments[1]", elem, val )
+def set_stored_msg_marker( msg_type ):
+ """Store marker text in the message buffer (so we can tell if the front-end changes it)."""
+ marker = "marker:{}:{}".format( msg_type, uuid.uuid4() )
+ set_stored_msg( msg_type, marker )
+ return marker
+
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
def find_child( sel, parent=None ):
@@ -295,6 +298,7 @@ def get_droplist_vals( sel ):
def dismiss_notifications():
"""Dismiss all notifications."""
+ assert False, "Shouldn't need to call this function." # nb: notifications have been disabled during tests
while True:
elem = find_child( ".growl-close" )
if not elem: