def generic_fill_out( context: Context, actor_alias: str, *, custom_details_table: Table = None, retry_on_errors: bool = False, go_back: bool = False, form_name: str = None, check_captcha_dev_mode: bool = True, ): if check_captcha_dev_mode: assert_catcha_in_dev_mode(context.driver) actor = get_actor(context, actor_alias) page = get_last_visited_page(context, actor_alias) has_action(page, "generate_form_details") has_action(page, "fill_out") if form_name: error = f"generate_form_details() in {page} should accept 'form_name' but it doesn't" assert signature( page.generate_form_details).parameters.get("form_name"), error error = f"fill_out() in {page} should accept 'form_name' but it doesn't" assert signature(page.fill_out).parameters.get("form_name"), error if custom_details_table: custom_details_table.require_column("field") custom_details_table.require_column("value") value_mapping = {"unchecked": False, "checked": True, "empty": None} custom_details = {} for row in custom_details_table.rows: key = row["field"].lower() value = row["value"] custom_details[key] = value_mapping.get(value, value) if form_name: details = page.generate_form_details(actor, custom_details=custom_details, form_name=form_name) else: details = page.generate_form_details(actor, custom_details=custom_details) else: if form_name: details = page.generate_form_details(actor, form_name=form_name) else: details = page.generate_form_details(actor) logging.debug(f"{actor_alias} will fill out the form with: {details}") update_actor_forms_data(context, actor, details) if form_name: page.fill_out(context.driver, details, form_name=form_name) else: page.fill_out(context.driver, details) if hasattr(page, "get_form_details"): logging.debug(f"Getting form details from filled out form: {page}") form_data = page.get_form_details(context.driver) if form_data: update_actor_forms_data(context, actor, form_data) else: if details: update_actor_forms_data(context, actor, details)
def generic_should_see_prepopulated_fields(context: Context, actor_alias: str, table: Table): table.require_columns(["form", "fields"]) expected_form_fields = { row.get("form"): [field.strip() for field in row.get("fields").split(",") if field] for row in table } error = f"Expected to check at least 1 list of form fields but got 0" assert expected_form_fields, error actor = get_actor(context, actor_alias) page = get_last_visited_page(context, actor_alias) field_values_to_check = {} for form_name, fields in expected_form_fields.items(): form_page_object = get_page_object(form_name) form_full_page_name = get_full_page_name(form_page_object) submitted_form_data = actor.forms_data[form_full_page_name] for field in fields: field_values_to_check[field] = submitted_form_data[field] logging.debug( f"Will check if form on '{get_full_page_name(page)}' is populated with " f"following values: {field_values_to_check}") has_action(page, "check_if_populated") page.check_if_populated(context.driver, field_values_to_check)
def conf2table(configuration): """ :param configparser.ConfigParser configuration: Configuration :return: Table :rtype: behave.model.Table """ table = Table(HEADINGS_INI) def s2s(s): return six.text_type(s, "utf-8") if six.PY2 else s for section in configuration.sections(): for key, value in configuration.items(section): table.add_row([s2s(section), s2s(key), s2s(value)]) return table
def write_step_module_overview(self, step_definitions): assert self.document headings = [u"Step Definition", u"Given", u"When", u"Then", u"Step"] table = Table(headings) step_type_cols = { "given": [u" x", u" ", u" ", u" "], "when": [u" ", u" x", u" ", u" "], "then": [u" ", u" ", u" x", u" "], "step": [u" x", u" x", u" x", u" x"], } for step_definition in step_definitions: row = [self.describe_step_definition(step_definition)] row.extend(step_type_cols[step_definition.step_type]) table.add_row(row) self.document.write_table(table)
def write_step_module_overview(self, step_definitions): assert self.document headings = ["Step Definition", "Given", "When", "Then", "Step"] table = Table(headings) step_type_cols = { # -- pylint: disable=bad-whitespace "given": [" x", " ", " ", " "], "when": [" ", " x", " ", " "], "then": [" ", " ", " x", " "], "step": [" x", " x", " x", " x"], } for step_definition in step_definitions: row = [self.describe_step_definition(step_definition)] row.extend(step_type_cols[step_definition.step_type]) table.add_row(row) self.document.write_table(table)
def step_rpmdb_does_not_change(ctx): """ Same as :ref:`Then rpmdb changes are`, but doesn't require table which means to apply only :ref:`rpmdb automatic rules <automatic rules>`. """ ctx.table = Table(HEADINGS_RPMDB) step_rpmdb_changes_are(ctx)
def given_empty_repository(ctx, repository): """ Same as :ref:`Given repository "{repository}" with packages`, but without packages (empty). """ ctx.table = Table(HEADINGS_REPO) given_repository_with_packages(ctx, False, "file", repository)
def test_non_daemon__negative_regex__do_match(dummy_context): from behave_cmdline.steps import _steps as s dummy_context.text = "echo 'SOME OUTPUT'" s.i_run_this_command(dummy_context) dummy_context.table = Table(headings=["mode", "shows", "value"], rows=[["regex", "N", "SOME ...PUT"]]) with pytest.raises(AssertionError): s.i_see_in_the_output_of(dummy_context, stream="stdout")
def test_non_daemon__positive_plain__do_match(dummy_context): from behave_cmdline.steps import _steps as s dummy_context.text = "echo 'SOME OUTPUT'" s.i_run_this_command(dummy_context) dummy_context.table = Table(headings=["mode", "shows", "value"], rows=[["plain", "Y", "SOME OUTPUT"]]) # MUST NOT RAISE s.i_see_in_the_output_of(dummy_context, stream="stdout")
def test_infinite_daemon__positive_regex__do_match(dummy_context): from behave_cmdline.steps import _steps as s dummy_context.text = "echo 'SOME OUTPUT' && while true; do sleep 1; done" s.i_launch_this_daemon(dummy_context) dummy_context.table = Table(headings=["mode", "shows", "value"], rows=[["regex", "Y", "SOME ...PUT"]]) # MUST NOT RAISE s.i_see_in_the_output_of(dummy_context, stream="stdout")
def test_daemon__timeout__negative_regex__do_match(dummy_context): from behave_cmdline.steps import _steps as s dummy_context.text = "sleep 10 && echo 'SOME OUTPUT'" s.i_launch_this_daemon(dummy_context) dummy_context.table = Table(headings=["mode", "shows", "value"], rows=[["regex", "N", "SOME ...PUT"]]) # MUST NOT RAISE s.i_see_in_the_output_of(dummy_context, stream="stdout", timeout=1)
def test_daemon__timeout__positive_regex__do_match(dummy_context): from behave_cmdline.steps import _steps as s dummy_context.text = "sleep 10 && echo 'SOME OUTPUT'" s.i_launch_this_daemon(dummy_context) dummy_context.table = Table(headings=["mode", "shows", "value"], rows=[["regex", "Y", "SOME ...PUT"]]) with pytest.raises(AssertionError): s.i_see_in_the_output_of(dummy_context, stream="stdout", timeout=1)
def test_non_daemon__negative_regex__dont_match(dummy_context): from behave_cmdline.steps import _steps as s dummy_context.text = "echo 'SOME OUTPUT'" s.i_run_this_command(dummy_context) dummy_context.table = Table(headings=["mode", "shows", "value"], rows=[["regex", "N", "\*\*OTHER\*\* ...PUT"]]) # MUST NOT RAISE s.i_see_in_the_output_of(dummy_context, stream="stdout")
def generic_check_gtm_datalayer_properties(context: Context, table: Table): row_names = [ "businessUnit", "loginStatus", "siteLanguage", "siteSection", "siteSubsection", "userId", ] table.require_columns(row_names) raw_properties = { name: row.get(name) for name in row_names for row in table } expected_properties = replace_string_representations(raw_properties) found_properties = get_gtm_data_layer_properties(context.driver) with assertion_msg( f"Expected to see following GTM data layer properties:\n" f"'{expected_properties}'\n but got:\n'{found_properties}'\non: " f"{context.driver.current_url}\ndiff:\n" f"{diff(expected_properties, found_properties)}"): assert expected_properties == found_properties
def test_execute_steps_with_table(self): doc = u""" Given a step with a table: | Name | Age | | Alice | 12 | | Bob | 23 | Then a step passes """.lstrip() with patch("behave.step_registry.registry", self.step_registry): # pylint: disable=bad-whitespace, bad-continuation result = self.context.execute_steps(doc) expected_table = Table([u"Name", u"Age"], 0, [ [u"Alice", u"12"], [u"Bob", u"23"], ]) eq_(result, True) eq_(expected_table, ExampleSteps.table)
def load_empty_table(context, model_name, vault_structure): """Creates an empty table""" context.target_model_name = model_name columns = context.vault_structure_columns if vault_structure == "stage": headings = context.stage_columns[model_name] else: headings = list( DBTVAULTGenerator.flatten( [val for key, val in columns[model_name].items()])) row = Row(cells=[], headings=headings) empty_table = Table(headings=headings, rows=row) seed_file_name = context.dbt_test_utils.context_table_to_csv( table=empty_table, model_name=model_name) dbtvault_generator.add_seed_config( seed_name=seed_file_name, seed_config=context.seed_config[model_name]) logs = context.dbt_test_utils.run_dbt_seed(seed_file_name=seed_file_name) if not vault_structure == "stage": metadata = { "source_model": seed_file_name, **context.vault_structure_columns[model_name] } context.vault_structure_metadata = metadata dbtvault_generator.raw_vault_structure(model_name, vault_structure, **metadata) logs = context.dbt_test_utils.run_dbt_model(mode="run", model_name=model_name) assert "Completed successfully" in logs
def convert_table_kv_to_skv(table, new_headings, new_column): """ Convert kv based table to skv based table by adding one extra column. :param behave.model.Table table: Original kv based table :param list new_headings: Headings for the skv based table (3 elements, where 2 of them are also in the original table) :param list new_column: Strings to be added as the new column (empty string is used when there is not enough items) :return: New skv based table :rtype: behave.model.Table """ headings = table.headings new_column_index = new_headings.index(list(set(new_headings) - set(headings))[0]) i = 0 new_rows = [] for row in table.rows: value = new_column[i] if i < len(new_column) else "" i += 1 new_values = row.cells[:] new_values.insert(new_column_index, value) new_row = Row(new_headings, new_values) new_rows.append(new_row) new_table = Table(new_headings, rows=new_rows) return new_table
def clear_schema(context): context.dbt_test_utils.replace_test_schema() model_names = context.dbt_test_utils.context_table_to_dict( table=context.table, orient="list") context.vault_model_names = model_names models = [ name for name in DBTVAULTGenerator.flatten( [v for k, v in model_names.items()]) if name ] for model_name in models: headings_dict = dbtvault_generator.evaluate_hashdiff( copy.deepcopy(context.vault_structure_columns[model_name])) headings = list( DBTVAULTGenerator.flatten( [v for k, v in headings_dict.items() if k != "source_model"])) row = Row(cells=[], headings=headings) empty_table = Table(headings=headings, rows=row) seed_file_name = context.dbt_test_utils.context_table_to_csv( table=empty_table, model_name=model_name) dbtvault_generator.add_seed_config( seed_name=seed_file_name, seed_config=context.seed_config[model_name]) logs = context.dbt_test_utils.run_dbt_seed( seed_file_name=seed_file_name) assert "Completed successfully" in logs
def given_repository_with_packages(ctx, rtype, repository): """ Builds dummy packages, creates repo and *.repo* file. Supported repo types are http, ftp or local (default). Supported architectures are x86_64, i686 and noarch (default). .. note:: Requires *rpmbuild* and *createrepo_c*. Requires table with following headers: ========= ===== ======= Package Tag Value ========= ===== ======= *Tag* is tag in RPM. Supported ones are: ============= =============== Tag Default value ============= =============== Summary Empty Version 1 Release 1 Arch x86_64 License Public Domain BuildRequires [] Requires [] Obsoletes [] Provides [] Conflicts [] ============= =============== All packages are built during step execution. .. note:: *BuildRequires* are ignored for build-time (*rpmbuild* is executed with ``--nodeps`` option). Examples: .. code-block:: gherkin Feature: Working with repositories Background: Repository base with dummy package Given http repository base with packages | Package | Tag | Value | | foo | | | Scenario: Installing dummy package from background When I enable repository base Then I successfully run "dnf -y install foo" """ packages = table_utils.parse_skv_table(ctx, HEADINGS_REPO, PKG_TAGS, PKG_TAGS_REPEATING) rpmbuild = which("rpmbuild") ctx.assertion.assertIsNotNone(rpmbuild, "rpmbuild is required") createrepo = which("createrepo_c") ctx.assertion.assertIsNotNone(createrepo, "createrepo_c is required") if rtype == 'http': tmpdir = tempfile.mkdtemp(dir='/var/www/html') repopath = os.path.join('localhost', os.path.basename(tmpdir)) elif rtype == 'ftp': tmpdir = tempfile.mkdtemp(dir='/var/ftp/pub') repopath = os.path.join('localhost/pub', os.path.basename(tmpdir)) else: tmpdir = tempfile.mkdtemp() repopath = tmpdir template = JINJA_ENV.from_string(PKG_TMPL) for name, settings in packages.items(): settings = {k.lower(): v for k, v in settings.items()} ctx.text = template.render(name=name, **settings) fname = "{!s}/{!s}.spec".format(tmpdir, name) step_a_file_filepath_with(ctx, fname) if 'arch' not in settings or settings['arch'] == 'noarch': cmd = "{!s} --define '_rpmdir {!s}' -bb {!s}".format( rpmbuild, tmpdir, fname) else: cmd = "setarch {!s} {!s} --define '_rpmdir {!s}' --target {!s} -bb {!s}".format( settings['arch'], rpmbuild, tmpdir, settings['arch'], fname) step_i_successfully_run_command(ctx, cmd) cmd = "{!s} {!s}".format(createrepo, tmpdir) step_i_successfully_run_command(ctx, cmd) # set proper directory content ownership file_utils.set_dir_content_ownership(ctx, tmpdir) repofile = REPO_TMPL.format(repository) ctx.table = Table(HEADINGS_INI) ctx.table.add_row([repository, "name", repository]) ctx.table.add_row(["", "enabled", "False"]) ctx.table.add_row(["", "gpgcheck", "False"]) ctx.table.add_row(["", "baseurl", "{!s}://{!s}".format(rtype, repopath)]) step_an_ini_file_filepath_with(ctx, repofile)
def setUp(self): self.table = Table(self.HEAD, 0, self.DATA)
def given_repository_with_packages(ctx, repository): """ Builds dummy noarch packages, creates repo and *.repo* file. .. note:: Requires *rpmbuild* and *createrepo_c*. Requires table with following headers: ========= ===== ======= Package Tag Value ========= ===== ======= *Tag* is tag in RPM. Supported ones are: ============= =============== Tag Default value ============= =============== Summary Empty Version 1 Release 1 License Public Domain BuildRequires [] Requires [] Obsoletes [] Provides [] ============= =============== All packages are built during step execution. .. note:: *BuildRequires* are ignored for build-time (*rpmbuild* is executed with ``--nodeps`` option). Examples: .. code-block:: gherkin Feature: Working with repositories Background: Repository base with dummy package Given repository base with packages | Package | Tag | Value | | foo | | | Scenario: Installing dummy package from background When I enable repository base Then I successfully run "dnf -y install foo" """ packages = table_utils.parse_skv_table(ctx, HEADINGS_REPO, PKG_TAGS, PKG_TAGS_REPEATING) rpmbuild = which("rpmbuild") ctx.assertion.assertIsNotNone(rpmbuild, "rpmbuild is required") createrepo = which("createrepo_c") ctx.assertion.assertIsNotNone(createrepo, "createrepo_c is required") tmpdir = tempfile.mkdtemp() template = JINJA_ENV.from_string(PKG_TMPL) for name, settings in packages.items(): settings = {k.lower(): v for k, v in settings.items()} ctx.text = template.render(name=name, **settings) fname = "{!s}/{!s}.spec".format(tmpdir, name) step_a_file_filepath_with(ctx, fname) cmd = "{!s} --define '_rpmdir {!s}' -bb {!s}".format( rpmbuild, tmpdir, fname) step_i_successfully_run_command(ctx, cmd) cmd = "{!s} {!s}".format(createrepo, tmpdir) step_i_successfully_run_command(ctx, cmd) repofile = REPO_TMPL.format(repository) ctx.table = Table(HEADINGS_INI) ctx.table.add_row([repository, "name", repository]) ctx.table.add_row(["", "enabled", "False"]) ctx.table.add_row(["", "gpgcheck", "False"]) ctx.table.add_row(["", "baseurl", "file://{!s}".format(tmpdir)]) step_an_ini_file_filepath_with(ctx, repofile)
def given_repository_with_packages(ctx, enabled, rtype, repository, gpgkey=None): """ Builds dummy packages, creates repo and *.repo* file. Supported repo types are http, https, ftp or local (default). Supported architectures are x86_64, i686 and noarch (default). .. note:: Along with the repository also *-source repository with src.rpm packages is built. The repository is disabled. .. note:: *https* repositories are configured to use certificates at following locations: /etc/pki/tls/certs/testcerts/ca/cert.pem /etc/pki/tls/certs/testcerts/client/key.pem /etc/pki/tls/certs/testcerts/client/cert.pem .. note:: Requires *rpmbuild* and *createrepo_c*. Requires table with following headers: ========= ===== ======= Package Tag Value ========= ===== ======= *Tag* is tag in RPM. Supported ones are: ================== =============== Tag Default value ================== =============== Summary Empty Version 1 Release 1 Arch x86_64 License Public Domain BuildRequires [] Requires [] Recommends [] Suggests [] Supplements [] Enhances [] Requires(pretrans) [] Requires(pre) [] Requires(post) [] Requires(preun) [] Obsoletes [] Provides [] Conflicts [] %pretrans Empty %pre Empty %post Empty %preun Empty %postun Empty %posttrans Empty ================== =============== All packages are built during step execution. .. note:: *BuildRequires* are ignored for build-time (*rpmbuild* is executed with ``--nodeps`` option). If there is a space character in the package name only the preceding part is used. .. note:: Scriptlets such as *%pre* can be listed multiple time so that the entering of a multi-line script is more comfortable. Examples: .. code-block:: gherkin Feature: Working with repositories Background: Repository base with dummy package Given http repository base with packages | Package | Tag | Value | | foo | | | Scenario: Installing dummy package from background When I enable repository base Then I successfully run "dnf -y install foo" Scenario: Creating repository with multiple package versions Given http repository "updates" with packages | Package | Tag | Value | | foo | Version | 2.0 | | foo v3 | Version | 3.0 | Scenario: Creating a package with %pre scriptlet failing Given http repository "more_updates" with packages | Package | Tag | Value | | foo | Version | 4.0 | | | %pre | exit 1 | """ packages = table_utils.parse_skv_table(ctx, HEADINGS_REPO, PKG_TAGS, PKG_TAGS_REPEATING) rpmbuild = which("rpmbuild") ctx.assertion.assertIsNotNone(rpmbuild, "rpmbuild is required") createrepo = which("createrepo_c") ctx.assertion.assertIsNotNone(createrepo, "createrepo_c is required") if rtype == 'http' or rtype == 'https': tmpdir = tempfile.mkdtemp(dir='/var/www/html') repopath = os.path.join('localhost', os.path.basename(tmpdir)) elif rtype == 'ftp': tmpdir = tempfile.mkdtemp(dir='/var/ftp/pub') repopath = os.path.join('localhost/pub', os.path.basename(tmpdir)) else: tmpdir = tempfile.mkdtemp() repopath = tmpdir srpm_tmpdir = '{}-source'.format(tmpdir.rstrip('/')) srpm_repopath = '{}-source'.format(repopath.rstrip('/')) os.mkdir(srpm_tmpdir) # create a directory for src.rpm pkgs template = JINJA_ENV.from_string(PKG_TMPL) for name, settings in packages.items(): name = name.split( )[0] # cut-off the pkg name _suffix_ to allow defining multiple package versions # before processing the template # lower all characters # replace '%' in Tag name with '_' # replace '(' in Tag name with '_' # delete all ')' in Tag settings = { k.lower().replace('%', '_').replace('(', '_').replace(')', ''): v for k, v in settings.items() } ctx.text = template.render(name=name, **settings) fname = "{!s}/{!s}.spec".format(tmpdir, name) step_a_file_filepath_with(ctx, fname) buildname = '%{NAME}-%{VERSION}-%{RELEASE}.%{ARCH}.rpm' if 'arch' not in settings or settings['arch'] == 'noarch': cmd = "{!s} --define '_rpmdir {!s}' --define '_srcrpmdir {!s}' --define '_build_name_fmt {!s}' -ba {!s}".format( rpmbuild, tmpdir, srpm_tmpdir, buildname, fname) else: cmd = "setarch {!s} {!s} --define '_rpmdir {!s}' --define '_srcrpmdir {!s}' --define '_build_name_fmt {!s}' --target {!s} -ba {!s}".format( settings['arch'], rpmbuild, tmpdir, srpm_tmpdir, buildname, settings['arch'], fname) step_i_successfully_run_command(ctx, cmd) if gpgkey: # sign all rpms built rpmsign = which("rpmsign") rpms = glob.glob("{!s}/*.rpm".format(tmpdir)) srpms = glob.glob("{!s}/*.rpm".format(srpm_tmpdir)) cmd = "{!s} --addsign --key-id '{!s}' {!s} {!s}".format( rpmsign, gpgkey, ' '.join(rpms), ' '.join(srpms)) step_i_successfully_run_command(ctx, cmd) cmd = "{!s} {!s}".format(createrepo, tmpdir) step_i_successfully_run_command(ctx, cmd) cmd = "{!s} {!s}".format(createrepo, srpm_tmpdir) step_i_successfully_run_command(ctx, cmd) # set proper directory content ownership file_utils.set_dir_content_ownership(ctx, tmpdir) file_utils.set_dir_content_ownership(ctx, srpm_tmpdir) repofile = REPO_TMPL.format(repository) ctx.table = Table(HEADINGS_INI) ctx.table.add_row([repository, "name", repository]) ctx.table.add_row(["", "enabled", six.text_type(enabled)]) ctx.table.add_row(["", "baseurl", "{!s}://{!s}".format(rtype, repopath)]) if gpgkey: ctx.table.add_row(["", "gpgcheck", "True"]) else: ctx.table.add_row(["", "gpgcheck", "False"]) if rtype == 'https': ctx.table.add_row( ["", "sslcacert", "/etc/pki/tls/certs/testcerts/ca/cert.pem"]) ctx.table.add_row([ "", "sslclientkey", "/etc/pki/tls/certs/testcerts/client/key.pem" ]) ctx.table.add_row([ "", "sslclientcert", "/etc/pki/tls/certs/testcerts/client/cert.pem" ]) step_an_ini_file_filepath_with(ctx, repofile) # create -source repository too srpm_repository = '{}-source'.format(repository) repofile = REPO_TMPL.format(srpm_repository) ctx.table = Table(HEADINGS_INI) ctx.table.add_row([srpm_repository, "name", srpm_repository]) ctx.table.add_row(["", "enabled", "False"]) ctx.table.add_row( ["", "baseurl", "{!s}://{!s}".format(rtype, srpm_repopath)]) if gpgkey: ctx.table.add_row(["", "gpgcheck", "True"]) else: ctx.table.add_row(["", "gpgcheck", "False"]) if rtype == 'https': ctx.table.add_row( ["", "sslcacert", "/etc/pki/tls/certs/testcerts/ca/cert.pem"]) ctx.table.add_row([ "", "sslclientkey", "/etc/pki/tls/certs/testcerts/client/key.pem" ]) ctx.table.add_row([ "", "sslclientcert", "/etc/pki/tls/certs/testcerts/client/cert.pem" ]) step_an_ini_file_filepath_with(ctx, repofile)