Tightened up how the tests retrieve notification messages from the front-end.

master
Pacman Ghost 6 years ago
parent 9a27bedf82
commit 26cbaf0845
  1. 8
      conftest.py
  2. 5
      vasl_templates/webapp/static/snippets.js
  3. 60
      vasl_templates/webapp/static/utils.js
  4. 4
      vasl_templates/webapp/templates/index.html
  5. 9
      vasl_templates/webapp/tests/test_ob.py
  6. 5
      vasl_templates/webapp/tests/test_scenario_persistence.py
  7. 18
      vasl_templates/webapp/tests/test_snippets.py
  8. 3
      vasl_templates/webapp/tests/test_ssr.py
  9. 32
      vasl_templates/webapp/tests/test_template_packs.py
  10. 7
      vasl_templates/webapp/tests/test_vehicles_ordnance.py
  11. 20
      vasl_templates/webapp/tests/utils.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.

@ -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" ) ;

@ -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 <div> we store the message in must be visible, otherwise
// Selenium doesn't return any text for it :-/
$elem = $( "<div id='" + id + "' style='z-index-999;'></div>" ) ;
$("body").append( $elem ) ;
}
$elem.html( msg ) ;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

@ -24,6 +24,10 @@
<input id="load-template-pack" type="file" accept=".zip,.j2" style="display:none;">
</div>
<!-- these are for the test suite -->
<textarea id="_last-info_" style="display:none;"></textarea>
<textarea id="_last-warning_" style="display:none;"></textarea>
<textarea id="_last-error_" style="display:none;"></textarea>
<textarea id="_template_pack_persistence_" style="display:none;"></textarea>
<!-- ----------------------------------------------------------------- -->

@ -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

@ -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:" )

@ -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

@ -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." )

@ -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 )

@ -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" )

@ -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:

Loading…
Cancel
Save