A search engine for MMP's eASLRB.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
asl-rulebook2/asl_rulebook2/webapp/tests/test_asop.py

311 lines
12 KiB

""" Test the ASOP. """
import os
import json
from asl_rulebook2.webapp.tests.test_search import do_search
from asl_rulebook2.webapp.tests.utils import init_webapp, select_tabbed_page, \
wait_for, wait_for_elem, find_child, find_children, unload_elem, unload_sr_text, \
check_sr_filters, get_image_filename, has_class
# ---------------------------------------------------------------------
def test_asop_nav( webdriver, webapp ):
"""Test the ASOP nav."""
# initialize
webapp.control_tests.set_data_dir( "asop" )
init_webapp( webapp, webdriver )
check_sr_filters( [ "index", "asop-entry" ] )
# load the ASOP
fname = os.path.join( os.path.dirname(__file__), "fixtures/asop/asop/index.json" )
with open( fname, "r", encoding="utf-8" ) as fp:
asop_index = json.load( fp )
# check the nav
select_tabbed_page( "nav", "asop" )
nav = unload_asop_nav( False )
chapters = asop_index["chapters"]
for chapter_no, chapter in enumerate( chapters ):
chapters[ chapter_no ] = {
key: val for key, val in chapter.items()
if key != "sniper_phase" and not key.startswith("_")
}
chapter.pop( "sniper_phase", None )
assert nav == asop_index["chapters"]
# check the footer
footer = find_child( "#asop-footer" )
assert "Sniper Attacks/Checks are possible" in footer.text
images = [
get_image_filename( c, full=True )
for c in find_children( "img", footer )
]
assert images == [
"/asop/images/attacker.png",
"/asop/images/defender.png",
"/asop/images/both-players.png"
]
# ---------------------------------------------------------------------
def test_asop_content( webdriver, webapp ):
"""Test the ASOP content."""
# initialize
webapp.control_tests.set_data_dir( "asop" )
init_webapp( webapp, webdriver )
select_tabbed_page( "nav", "asop" )
nav = unload_asop_nav( True )
def load_asop_file( fname, as_json ):
"""Load an ASOP data file."""
fname = os.path.join( base_dir, fname )
if not os.path.isfile( fname ):
return None
with open( fname, "r", encoding="utf-8" ) as fp:
return json.load( fp ) if as_json else fp.read()
# load the ASOP index
base_dir = os.path.join( os.path.dirname(__file__), "fixtures/asop/asop/" )
asop_index = load_asop_file( "index.json", True )
def check_chapter( chapter_no, callbacks ):
"""Check the specified ASOP chapter."""
# open the chapter
expected_chapter = asop_index["chapters"][ chapter_no ]
nav[ chapter_no ][ "elem" ].click()
expected = len( expected_chapter["sections"] )
wait_for( 2, lambda: len( find_children( "#asop .sections .section" ) ) == expected )
# check the title
title = find_child( "#asop .title" ).text
expected = expected_chapter[ "caption" ]
if expected_chapter.get( "sniper_phase" ):
expected += "\u2020"
assert title == expected
chapter_id = find_child( "#asop" ).get_attribute( "data-chapterid" )
assert chapter_id == expected_chapter["chapter_id"]
# check the preamble
expected_preamble = load_asop_file( "{}-0.html".format( chapter_id ), False )
preamble = find_child( "#asop .preamble" ).text
if preamble:
# NOTE: We only check the first few characters since the data file is processed as a template,
# so it may not match exactly what's in the UI.
assert preamble[0:20] in expected_preamble
else:
assert preamble == ""
# do any chapter-specific checks
func = callbacks.get( "check_{}".format( chapter_id.replace("-","_") ) )
if func:
func()
# check each section (in the combined view)
expected_sections = expected_chapter[ "sections" ]
section_elems = find_children( "#asop .sections .section" )
assert len(expected_sections) == len(section_elems)
for section_no in range( len(expected_sections) ):
# check the section's caption
caption = find_child( ".caption", section_elems[section_no] ).text
assert caption == expected_sections[section_no]["caption"]
# check the section's content
section_id = "{}-{}".format( chapter_id, 1+section_no )
expected_content = load_asop_file( section_id+".html", False )
content = find_child( "ul", section_elems[section_no] ).text
assert content[0:20] in expected_content
# check each individual section
def check_title():
return find_child( "#asop .title" ).text == expected
for section_no, nav_section in enumerate( nav[chapter_no]["sections"] ):
# click on the section in the nav pane
find_child( "a", nav_section["elem"] ).click()
# wait for the section's content to appear
expected = expected_sections[ section_no ][ "caption" ]
if expected_chapter.get( "sniper_phase" ):
expected += "\u2020"
wait_for( 2, check_title )
# check the preamble
# NOTE: The preamble is part of the parent chapter, and so should remain unchanged.
preamble = find_child( "#asop .preamble" ).text
if preamble:
assert preamble[0:20] in expected_preamble
else:
assert preamble == ""
# check the section's content
section_id = "{}-{}".format( chapter_id, 1+section_no )
expected_content = load_asop_file( section_id+".html", False )
sections = find_children( "#asop .sections .section" )
assert len(sections) == 1
content = find_child( "ul", sections[0] ).text
assert content[0:20] in expected_content
# do any section-specific checks
func = callbacks.get( "check_{}_section".format( chapter_id.replace("-","_") ) )
if func:
func( 1+section_no )
def check_pre_game(): #pylint: disable=possibly-unused-variable
# check the DYO image in the preamble
assert get_image_filename( find_child("#asop .preamble img.icon"), full=True ) == "/asop/images/dyo.png"
# check the images in the sections
images = set(
get_image_filename( c, full=True )
for c in find_children( "#asop .sections .section img.icon" )
)
assert images == set( [
"/asop/images/dyo.png", "/asop/images/both-players.png"
] )
def check_pre_game_section( section_no ): #pylint: disable=possibly-unused-variable
if section_no == 1:
# check the DYO image in the preamble
assert get_image_filename( find_child("#asop .preamble img.icon"), full=True ) == "/asop/images/dyo.png"
def check_rally(): #pylint: disable=possibly-unused-variable
# check the EXC block in the preamble
assert has_class( find_child( "#asop .preamble span" ), "exc" )
def check_movement(): #pylint: disable=possibly-unused-variable
# there should be 3 EXC blocks
elems = [
c for c in find_children( "#asop .sections .section span" )
if has_class( c, "exc" )
]
elems = set( e.text for e in elems ) # why are we seeing everything twice?! :-/
assert len(elems) == 3
def check_movement_section( section_no ): #pylint: disable=possibly-unused-variable
# check an EXC block
if section_no == 5:
assert has_class( find_child( "#asop .sections .section span" ), "exc" )
# check each chapter
for i in range( 0, 8+1 ):
check_chapter( i, locals() )
# check error handling
nav[ 9 ][ "elem" ].click()
sections = find_children( "#asop .sections .section" )
assert len(sections) == 0
# ---------------------------------------------------------------------
def test_asop_entries( webdriver, webapp ):
"""Test searching for individual ASOP entries."""
# initialize
webapp.control_tests.set_data_dir( "asop" )
init_webapp( webapp, webdriver )
def do_test( query_string, expected ):
# do the search
results = do_search( query_string )
# check the search results
assert len(results) == len(expected)
for i in range( len(results) ):
assert expected[i][0] in results[i]["content"]
assert expected[i][1]in results[i]["content"]
# make sure we can click through to the ASOP
sr_elems = find_children( "#search-results .asop-entry-sr" )
for sr_no, sr_elem in enumerate( sr_elems ):
# click on the search result
find_child( ".caption", sr_elem ).click()
wait_for_elem( 2, "#asop" )
# check the contents of the ASOP popup
entries = find_children( "#asop .sections .section .entry" )
assert len(entries) == 1
assert expected[sr_no][0] in unload_sr_text( entries[0] )
# check the nav pane
panes = [
c for c in find_children( "#accordian-asop .accordian-pane" )
if find_child( ".entries", c ).value_of_css_property( "display" ) != "none"
]
assert len(panes) == 1
assert panes[0].get_attribute( "data-chapterid" ) == expected[sr_no][2]
# return back to the Search nav pane
select_tabbed_page( "nav", "search" )
# do the tests
do_test( "napalm", [
[ "2.11A", "checking for any ((Napalm)) terrain-Blaze/weapon", "prep-fire" ]
] )
do_test( "reverse", [
[ "2.15A", "((Reverse)) Slopes", "prep-fire" ],
[ "4.14D", "((Reverse)) Slopes", "defensive-fire" ],
] )
do_test( '"mop up"', [
[ "2.21A", "((Mop Up)) (A12.153)", "prep-fire" ]
] )
do_test( '"crew become TI"', [
[ "2.23A", "it and ((crew become TI))", "prep-fire" ],
[ "4.22D", "it and ((crew become TI))", "defensive-fire" ],
] )
# search for something that is not part of an "entry" div
results = do_search( "porpoise" )
assert results is None
# ---------------------------------------------------------------------
def open_asop_chapter( chapter_id, nav=None ):
"""Open the specified ASOP chapter."""
if not nav:
nav = unload_asop_nav( True )
for chapter in nav:
if chapter["chapter_id"] == chapter_id:
chapter["elem"].click()
wait_for( 2, lambda: find_child("#asop").get_attribute("data-chapterid") == chapter_id )
return chapter
assert False, "Can't find ASOP chapter: "+chapter_id
return None # nb: for pylint :-/
def open_asop_section( chapter_id, section_no, nav=None ):
"""Open the specified ASOP section."""
chapter = open_asop_chapter( chapter_id, nav )
chapter["sections"][ section_no ]["elem"].click()
wait_for( 2, lambda: find_child( "#asop .sections.single" ) )
def unload_asop_nav( include_elems ):
"""Unload the ASOP nav."""
chapters = []
for chapter_elem in find_children( "#accordian-asop .accordian-pane" ):
# unload the next chapter
chapter = {
"chapter_id": chapter_elem.get_attribute( "data-chapterid" ),
}
unload_elem( chapter, "caption", find_child(".title",chapter_elem) )
if include_elems:
chapter[ "elem" ] = chapter_elem
# unload the chapter's sections
chapter_elem.click() # nb: panes must be open to unload their sections :-/
sections = []
for section_elem in find_children( ".entry", chapter_elem ):
sections.append( {
"caption": section_elem.text,
} )
if include_elems:
sections[-1]["elem"] = section_elem
if sections:
chapter[ "sections" ] = sections
chapters.append( chapter )
return chapters