Allow tests to be run headless.

master
Pacman Ghost 6 years ago
parent dbc5292926
commit 971e902988
  1. 3
      .pylintrc
  2. 36
      conftest.py
  3. 2
      vasl_templates/webapp/static/main.js
  4. 8
      vasl_templates/webapp/static/snippets.js
  5. 13
      vasl_templates/webapp/static/utils.js
  6. 3
      vasl_templates/webapp/templates/index.html
  7. 4
      vasl_templates/webapp/tests/test_scenario_persistence.py
  8. 2
      vasl_templates/webapp/tests/test_snippets.py
  9. 8
      vasl_templates/webapp/tests/test_template_packs.py
  10. 14
      vasl_templates/webapp/tests/utils.py

@ -137,7 +137,8 @@ disable=print-statement,
bad-whitespace,
bad-continuation,
invalid-name,
wrong-import-position
wrong-import-position,
global-statement
# Enable the message, report, category or checker with the given id(s). You can
# either give multiple identifier separated by comma (,) or put this option

@ -23,17 +23,29 @@ def pytest_addoption( parser ):
# NOTE: This file needs to be in the project root for this to work :-/
# add an option to control which webdriver to use
# add test options
parser.addoption(
"--webdriver", action="store", dest="webdriver", default="firefox",
help="Webdriver to use."
)
parser.addoption(
"--headless", action="store_true", dest="headless", default=False,
help="Run the tests headless."
)
parser.addoption(
"--window-size", action="store", dest="window_size", default="1000x700",
help="Browser window size."
)
# add an option to control checking of vehicle/ordnance reports
# add test options
parser.addoption(
"--no-clipboard", action="store_true", dest="no_clipboard", default=False,
help="Don't use the clipboard to get snippets."
)
parser.addoption(
"--vo-reports", action="store_true", dest="check_vo_reports", default=False,
help="Check the vehicle/ordnance reports."
)
)
# ---------------------------------------------------------------------
@ -46,6 +58,13 @@ def webapp():
def make_webapp_url( endpoint, **kwargs ):
"""Generate a webapp URL."""
with app.test_request_context():
if pytest.config.option.headless: #pylint: disable=no-member
# headless browsers have no clipboard support :-/
pytest.config.option.no_clipboard = True #pylint: disable=no-member
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.
kwargs["store_clipboard"] = 1
url = url_for( endpoint, _external=True, **kwargs )
return url.replace( "localhost/", "localhost:{}/".format(FLASK_WEBAPP_PORT) )
app.url_for = make_webapp_url
@ -105,14 +124,23 @@ def webdriver( request ):
driver = request.config.getoption( "--webdriver" )
from selenium import webdriver as wb
if driver == "firefox":
options = wb.FirefoxOptions()
options.set_headless( headless = pytest.config.option.headless ) #pylint: disable=no-member
driver = wb.Firefox(
firefox_options = options,
log_path = os.path.join( tempfile.gettempdir(), "geckodriver.log" )
)
elif driver == "chrome":
driver = wb.Chrome()
options = wb.ChromeOptions()
options.set_headless( headless = pytest.config.option.headless ) #pylint: disable=no-member
driver = wb.Chrome( chrome_options=options )
else:
assert False, "Unknown webdriver: {}".format( driver )
# set the browser size
words = pytest.config.option.window_size.split( "x" ) #pylint: disable=no-member
driver.set_window_size( int(words[0]), int(words[1]) )
# return the webdriver to the caller
utils._webdriver = driver #pylint: disable=protected-access
yield driver

@ -297,7 +297,7 @@ $(document).ready( function () {
template_id = "vehicles" ;
else if ( template_id.substring(0,9) === "ordnance_" )
template_id = "ordnance" ;
$( "<a href='#' class='edit-template-link' data-id='" + template_id + "'" +
$( "<a href='#' class='_edit-template-link_' data-id='" + template_id + "'" +
" onclick='edit_template(\"" + template_id + "\")'" +
"></a>"
).appendTo( "body" ) ;

@ -446,7 +446,7 @@ function on_load_scenario()
// FOR TESTING PORPOISES! We can't control a file upload from Selenium (since
// the browser will use native controls), so we store the result in a <div>).
if ( getUrlParam( "scenario_persistence" ) ) {
var $elem = $( "#scenario_persistence" ) ; // nb: must have already been created
var $elem = $( "#_scenario_persistence_" ) ; // nb: must have already been created
do_load_scenario( JSON.parse( $elem.val() ) ) ;
return ;
}
@ -610,11 +610,11 @@ function on_save_scenario()
// FOR TESTING PORPOISES! We can't control a file download from Selenium (since
// the browser will use native controls), so we store the result in a <div>).
if ( getUrlParam( "scenario_persistence" ) ) {
var $elem = $( "#scenario_persistence" ) ;
var $elem = $( "#_scenario_persistence_" ) ;
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 = $( "<textarea id='scenario_persistence' style='z-index-999;'></textarea>" ) ;
$elem = $( "<textarea id='_scenario_persistence_' style='z-index-999;'></textarea>" ) ;
$("body").append( $elem ) ;
}
$elem.val( data ) ;
@ -684,7 +684,7 @@ function on_template_pack()
// FOR TESTING PORPOISES! We can't control a file upload from Selenium (since
// the browser will use native controls), so we store the result in a <div>).
if ( getUrlParam( "template_pack_persistence" ) ) {
var data = $( "#template_pack_persistence" ).val() ; // nb: must have already been created
var data = $( "#_template_pack_persistence_" ).val() ; // nb: must have already been created
var pos = data.indexOf( "|" ) ;
var fname = data.substring( 0, pos ).trim() ;
data = data.substring( pos+1 ).trim() ;

@ -3,6 +3,19 @@
function copyToClipboard( val )
{
if ( getUrlParam( "store_clipboard" ) ) {
// store the value where the tests can retrieve it
var $elem = $("#_clipboard_") ;
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 = $( "<textarea id='_clipboard_' style='z-index-999;'></textarea>" ) ;
$("body").append( $elem ) ;
}
$("#_clipboard_").text( val ) ;
return ;
}
// IE-specific code path to prevent textarea being shown while dialog is visible
if ( window.clipboardData && window.clipboardData.setData ) {
clipboardData.setData( "Text", val ) ;

@ -22,9 +22,10 @@
<input type="button" value="actions">
<input id="load-scenario" type="file" accept=".json" style="display:none;">
<input id="load-template-pack" type="file" accept=".zip,.j2" style="display:none;">
<textarea id="template_pack_persistence" style="display:none;"></textarea>
</div>
<textarea id="_template_pack_persistence_" style="display:none;"></textarea>
<!-- ----------------------------------------------------------------- -->
<div id="tabs">

@ -182,11 +182,11 @@ def test_unknown_vo( webapp, webdriver ):
def _load_scenario( scenario ):
"""Load a scenario into the UI."""
set_stored_msg( "scenario_persistence", json.dumps(scenario) )
set_stored_msg( "_scenario_persistence_", json.dumps(scenario) )
select_menu_option( "load_scenario" )
def _save_scenario():
"""Save the scenario."""
select_menu_option( "save_scenario" )
data = get_stored_msg( "scenario_persistence" )
data = get_stored_msg( "_scenario_persistence_" )
return json.loads( data )

@ -179,7 +179,7 @@ def test_edit_templates( webapp, webdriver ):
if template_id in("scenario_note","ob_setup","ob_note"):
return # nb: these require special handling (done below)
# edit the template
elem = find_child( "a.edit-template-link[data-id='{}']".format( template_id ) )
elem = find_child( "a._edit-template-link_[data-id='{}']".format( template_id ) )
webdriver.execute_script( "$(arguments[0]).click();", elem )
edit_template( orig_template_id )
# check that the new template is being used

@ -30,7 +30,7 @@ def test_individual_files( webapp, webdriver ):
assert clipboard != ""
# upload a new template
fname = template_id + ".j2"
set_stored_msg( "template_pack_persistence",
set_stored_msg( "_template_pack_persistence_",
"{} | {}".format( fname, "UPLOADED TEMPLATE" )
)
select_menu_option( "template_pack" )
@ -41,7 +41,7 @@ def test_individual_files( webapp, webdriver ):
for_each_template( test_template )
# try uploading a template with an incorrect filename extension
set_stored_msg( "template_pack_persistence",
set_stored_msg( "_template_pack_persistence_",
"filename.xyz | UPLOADED TEMPLATE"
)
select_menu_option( "template_pack" )
@ -49,7 +49,7 @@ def test_individual_files( webapp, webdriver ):
assert "Invalid template extension" in last_error_msg
# try uploading a template with an unknown filename
set_stored_msg( "template_pack_persistence",
set_stored_msg( "_template_pack_persistence_",
"unknown.j2 | UPLOADED TEMPLATE"
)
select_menu_option( "template_pack" )
@ -203,7 +203,7 @@ def _generate_snippet( template_id, orig_template_id ):
def _upload_template_pack( zip_data ):
"""Upload a template pack."""
set_stored_msg( "template_pack_persistence",
set_stored_msg( "_template_pack_persistence_",
"{} | {}".format( "test.zip", base64.b64encode(zip_data).decode("ascii") )
)
select_menu_option( "template_pack" )

@ -6,6 +6,7 @@ import json
import time
import re
import pytest
from PyQt5.QtWidgets import QApplication
from selenium.webdriver.support.ui import Select
from selenium.webdriver.common.keys import Keys
@ -316,11 +317,18 @@ def click_dialog_button( caption ):
# ---------------------------------------------------------------------
_pyqt_app = None
def get_clipboard() :
"""Get the contents of the clipboard."""
app = QApplication( [] ) #pylint: disable=unused-variable
clipboard = QApplication.clipboard()
return clipboard.text()
if pytest.config.option.no_clipboard: #pylint: disable=no-member
return get_stored_msg( "_clipboard_" )
else:
global _pyqt_app
if _pyqt_app is None:
_pyqt_app = QApplication( [] )
clipboard = QApplication.clipboard()
return clipboard.text()
def wait_for( timeout, func ):
"""Wait for a condition to become true."""

Loading…
Cancel
Save