#!/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()