#!/usr/bin/python3
# checkpoint:
# 1. create blueprint
# 2. blueprint filter
# 3. blueprint sort
import re
import composerlib
import testlib
@testlib.nondestructive
class TestBlueprint(composerlib.ComposerCase):
def testCreate(self):
b = self.browser
self.login_and_go("/composer", authorized=True)
b.wait_present("#main")
# create blueprint
b.click(".toolbar-pf-action-right #cmpsr-btn-crt-blueprint")
b.wait_present("div[role=dialog] #cmpsr-modal-crt-blueprint")
# empty name blueprint
b.set_input_text("#textInput-modal-markup", "")
b.set_input_text("#textInput2-modal-markup", "test")
# should have error message and disable Create button
b.wait_text("#cmpsr-modal-crt-blueprint .help-block", "A blueprint name is required.")
b.wait_attr("#create-blueprint-modal-create-button", "disabled", "")
b.click("#cmpsr-modal-crt-blueprint button:contains('Cancel')")
b.wait_not_present("div[role=dialog] #cmpsr-modal-crt-blueprint")
# invalid characters for blueprint name
invalid_chars = {
" ": "spaces.",
"$": "the character: $",
"/*": "the characters: / *",
"= ": "spaces or the character: =",
" ! '": "spaces or the characters: ! '"
}
for c in invalid_chars.keys():
b.click(".toolbar-pf-action-right #cmpsr-btn-crt-blueprint")
b.wait_present("div[role=dialog] #cmpsr-modal-crt-blueprint")
# empty name blueprint
b.set_input_text("#textInput-modal-markup", "-_.{}".format(c))
b.wait_text("#cmpsr-modal-crt-blueprint .help-block",
"Blueprint names cannot contain {}".format(invalid_chars[c]))
b.click("#cmpsr-modal-crt-blueprint .modal-header .close")
b.wait_not_present("div[role=dialog] #cmpsr-modal-crt-blueprint")
# duplicate name
# wait until the openssh-server blueprint is there
b.wait_in_text("ul[aria-label=Blueprints]", "openssh-server")
b.click(".toolbar-pf-action-right #cmpsr-btn-crt-blueprint")
b.wait_present("div[role=dialog] #cmpsr-modal-crt-blueprint")
# empty name blueprint
b.set_input_text("#textInput-modal-markup", "openssh-server")
b.set_input_text("#textInput2-modal-markup", "openssh server image")
b.wait_text("#cmpsr-modal-crt-blueprint .help-block",
"The name openssh-server already exists.")
b.click("#cmpsr-modal-crt-blueprint button:contains('Cancel')")
b.wait_not_present("div[role=dialog] #cmpsr-modal-crt-blueprint")
# duplicate name (by pressing enter)
# wait until the openssh-server blueprint is there
b.wait_in_text("ul[aria-label=Blueprints]", "openssh-server")
b.click(".toolbar-pf-action-right #cmpsr-btn-crt-blueprint")
b.wait_present("div[role=dialog] #cmpsr-modal-crt-blueprint")
# empty name blueprint
b.set_input_text("#textInput-modal-markup", "openssh-server")
b.key_press("\r")
b.wait_text("#cmpsr-modal-crt-blueprint .alert-danger", "Specify a new blueprint name.")
b.click("#cmpsr-modal-crt-blueprint button:contains('Cancel')")
b.wait_not_present("div[role=dialog] #cmpsr-modal-crt-blueprint")
# collect code coverage result
self.check_coverage()
def testFilter(self):
b = self.browser
self.login_and_go("/composer", authorized=True)
b.wait_present("#main")
# filter "openssh-server" blueprint
b.set_input_text("#filter-blueprints", "openssh")
b.key_press("\r")
b.wait_in_text(".filter-pf-active-label + .list-inline .label", "Name: openssh")
b.wait_present("#openssh-server-name")
b.wait_not_present("#httpd-server-name")
# clear filter
b.click(".filter-pf-active-label + .list-inline .pficon-close")
b.wait_not_present("p:contains('Active Filters:')")
# filter "httpd" will show three matched blueprints
b.set_input_text("#filter-blueprints", "httpd")
b.key_press("\r")
b.wait_in_text(".filter-pf-active-label + .list-inline .label", "Name: httpd")
b.wait_not_present("#openssh-server-name")
b.wait_present("#httpd-server-name")
b.wait_present("#httpd-server-with-hostname-name")
b.wait_present("#httpd-server-with-user-name")
# clear filter
b.click("button:contains('Clear All Filters')")
b.wait_not_present("p:contains('Active Filters:')")
# collect code coverage result
self.check_coverage()
def testSort(self):
b = self.browser
self.login_and_go("/composer", authorized=True)
b.wait_present("#main")
blueprint_list = [
"httpd-server",
"httpd-server-with-hostname",
"httpd-server-with-user",
"openssh-server"
]
# sort from Z-A
b.wait_present("ul[aria-label=Blueprints]")
b.click(".fa-sort-alpha-asc")
b.wait_present(".fa-sort-alpha-desc")
for i, v in enumerate(sorted(blueprint_list, reverse=True)):
b.wait_text("ul[aria-label=Blueprints] li:nth-child({}) a strong".format(i + 1), v)
# sort from A-Z
b.click(".fa-sort-alpha-desc")
b.wait_present(".fa-sort-alpha-asc")
for i, v in enumerate(sorted(blueprint_list)):
b.wait_text("ul[aria-label=Blueprints] li:nth-child({}) a strong".format(i + 1), v)
# collect code coverage result
self.check_coverage()
def testExport(self):
b = self.browser
m = self.machine
self.login_and_go("/composer", authorized=True)
b.wait_present("#main")
# export package list
actions_drop_down_sel = "#openssh-server-kebab"
b.click(actions_drop_down_sel)
b.wait_attr(actions_drop_down_sel, "aria-expanded", "true")
b.click("li[data-blueprint=openssh-server] a:contains('Export')")
b.wait_present("#cmpsr-modal-export")
with b.wait_timeout(300):
b.wait_in_text("#textInput2-modal-markup", "openssh-server")
packages_list = b.text("#textInput2-modal-markup")
b.click("#cmpsr-modal-export button[data-btn=copy-export]")
b.click("#cmpsr-modal-export button[data-btn=close-export]")
b.wait_not_present("#cmpsr-modal-export")
list_from_backend = m.execute("""
composer-cli blueprints depsolve openssh-server | tail -n +2
""").split()
# remove tailing ".x86_64" or ".noarch"(6 chars) or ".aarch64"(7 chars)
# and "*:" in libpcap-14:1.9.1-2.fc31.x86_64
regex = re.compile("-[0-9]*:")
def remove(x):
if x.endswith("aarch64"):
return regex.sub("-", x[:-8])
else:
return regex.sub("-", x[:-7])
format_list = map(remove, list_from_backend)
self.assertEqual(packages_list, "\n".join(format_list))
# collect code coverage result
self.check_coverage()
if __name__ == '__main__':
testlib.test_main()