diff --git a/app/experimenter/static/js/components/AddonForm.js b/app/experimenter/static/js/components/AddonForm.js index df3b8dd2c9..63e4b75d82 100644 --- a/app/experimenter/static/js/components/AddonForm.js +++ b/app/experimenter/static/js/components/AddonForm.js @@ -25,6 +25,7 @@ export default class AddonForm extends React.PureComponent { { this.props.handleDataChange("addon_release_url", value); diff --git a/app/tests/integration/conftest.py b/app/tests/integration/conftest.py index 742599f0f8..3a4de2f13f 100644 --- a/app/tests/integration/conftest.py +++ b/app/tests/integration/conftest.py @@ -56,6 +56,9 @@ def fill_overview(selenium, base_url, ds_issue_host, request, variables): home = Home(selenium, base_url).wait_for_page_to_load() experiment = home.create_experiment() experiment_type = getattr(request.module, "experiment_type", None) + experiment.experiment_type = getattr( + request.module, "experiment_type_name", "Pref-Flip Experiment" + ) if request.node.get_closest_marker("use_variables"): experiment.name = f"{variables[experiment_type]['name']}" experiment.short_description = "Testing in here" @@ -188,6 +191,37 @@ def fill_design_page_single_pref(selenium, base_url, request, variables, fill_ov return design +@pytest.fixture +def fill_design_page_branched_single_addon( + selenium, base_url, request, variables, fill_overview +): + """Fills design page according to branched single addon requirements.""" + experiment_type = getattr(request.module, "experiment_type", None) + design = DesignPage(selenium, base_url, experiment_url=f"{fill_overview.url}").open() + design = design.wait_for_page_to_load() + design.signed_addon_url = f"{variables[experiment_type]['addon_url']}" + current_branchs = design.current_branches + control_branch = current_branchs[0] + control_branch.branch_name = ( + f"{variables[experiment_type]['branches'][0]['branch_name']}" + ) + control_branch.branch_description = "THIS IS A TEST" + control_branch.branch_description = ( + f"{variables[experiment_type]['branches'][0]['branch_description']}" + ) + current_branchs[ + 1 + ].branch_name = f"{variables[experiment_type]['branches'][1]['branch_name']}" + current_branchs[1].branch_description = "THIS IS A TEST" + current_branchs[ + 1 + ].branch_description = ( + f"{variables[experiment_type]['branches'][1]['branch_description']}" + ) + design.save_btn() + return design + + @pytest.fixture def fill_analysis_page(selenium, base_url, request, variables, fill_overview): """Fills analysis page.""" diff --git a/app/tests/integration/e2e_test_variables.json b/app/tests/integration/e2e_test_variables.json index b4b8cd8b25..15166ce7c4 100644 --- a/app/tests/integration/e2e_test_variables.json +++ b/app/tests/integration/e2e_test_variables.json @@ -72,5 +72,28 @@ ] } ] + }, + "branched-addon-study": { + "action_name": "branched-addon-study", + "name":"E2E experimenter single-pref-addon-test", + "addon_url": "https://url.com/addon-url.xpi", + "type": "channel", + "channels": "Nightly", + "min_version": "80.0", + "max_version": "100.0", + "userFacingName": "e2e testing addon name", + "userFacingDescription": "e2e testing addon description", + "branches": [ + { + "branch_description": "e2e Branch Description", + "branch_name": "e2e-addon-branch" + + }, + { + "branch_description": "e2e Branch Description second branch", + "branch_name": "e2e-addon-branch-2" + } + ] + } } \ No newline at end of file diff --git a/app/tests/integration/pages/experiment_design.py b/app/tests/integration/pages/experiment_design.py index 7ea593cb39..b9fdc81d1a 100644 --- a/app/tests/integration/pages/experiment_design.py +++ b/app/tests/integration/pages/experiment_design.py @@ -23,6 +23,7 @@ class DesignPage(Base): _firefox_pref_branch_locator = (By.CSS_SELECTOR, "#id_pref_branch") _multipref_radio_btn_locator = (By.CSS_SELECTOR, "#is_multi_pref-true") _new_branch_locator = (By.CSS_SELECTOR, "#add-branch-button") + _signed_addon_url_locator = (By.CSS_SELECTOR, "#signed-addon-url") def wait_for_page_to_load(self): self.wait.until( @@ -74,6 +75,21 @@ def select_firefox_pref_branch(self, item): selector.select_by_visible_text(f"{item}") return + @property + def signed_addon_url(self): + element = self.find_element(*self._signed_addon_url_locator) + return element.text + + @signed_addon_url.setter + def signed_addon_url(self, text=None): + try: + assert self.signed_addon_url == "", "Form field not empty" + except AssertionError: + return + else: + element = self.find_element(*self._signed_addon_url_locator) + element.send_keys(text) + def click_continue(self): self.find_element(*self._continue_btn_locator).click() return diff --git a/app/tests/integration/pages/experiment_overview.py b/app/tests/integration/pages/experiment_overview.py index b76938f8b7..5264609b17 100644 --- a/app/tests/integration/pages/experiment_overview.py +++ b/app/tests/integration/pages/experiment_overview.py @@ -2,6 +2,7 @@ import string from selenium.webdriver.common.by import By +from selenium.webdriver.support.select import Select from pages.base import Base @@ -27,7 +28,7 @@ class ExperimentOverview(Base): ".filter-option-inner-inner", ) _experiment_related_work_url_locator = (By.CSS_SELECTOR, "#id_related_work") - _experiment_type_locator = (By.CSS_SELECTOR, "#id_type > option") + _experiment_type_locator = (By.CSS_SELECTOR, "#id_type") _related_experiments_dropdown = (By.CSS_SELECTOR, "ul.dropdown-menu > li > a") _page_wait_locator = (By.CSS_SELECTOR, "body.page-edit-overview") _name_locator = (By.CSS_SELECTOR, "#id_name") @@ -50,17 +51,17 @@ def wait_for_page_to_load(self): @property def experiment_type(self): - options = self.find_elements(*self._experiment_type_locator) + options = self.find_element(*self._experiment_type_locator) + options = options.find_elements_by_css_selector("option") for item in options: if item.get_property("selected"): - return item.get_attribute("value") + return item.text @experiment_type.setter def experiment_type(self, exp_type=None): - types = self.find_elements(*self._experiment_type_locator) - for option in types: - if exp_type in option.text.replace("-", "").lower(): - option.click() + types = self.find_element(*self._experiment_type_locator) + selector = Select(types) + selector.select_by_visible_text(f"{exp_type}") @property def name(self): diff --git a/app/tests/integration/test_branched_addon_e2e.py b/app/tests/integration/test_branched_addon_e2e.py new file mode 100644 index 0000000000..a5a0cfe9fe --- /dev/null +++ b/app/tests/integration/test_branched_addon_e2e.py @@ -0,0 +1,67 @@ +import json +from urllib.parse import urlparse + +import pytest +import requests + +experiment_type = "branched-addon-study" +experiment_type_name = "Add-On Experiment" + + +@pytest.mark.use_variables +@pytest.mark.nondestructive +def test_branched_addon_e2e( + base_url, + selenium, + fill_timeline_page, + fill_design_page_branched_single_addon, + fill_analysis_page, + fill_risks_page, + signoff_and_ship, +): + url = urlparse(selenium.current_url) + experiment_url = f"{url.scheme}://{url.netloc}/api/v1{url.path}recipe/" + experiment_json = requests.get(f"{experiment_url}", verify=False).json() + with open("e2e_test_variables.json", "r") as j: + test_json = json.load(j) + assert test_json[experiment_type]["name"] in experiment_json["name"] + assert test_json[experiment_type]["action_name"] == experiment_json["action_name"] + assert ( + test_json[experiment_type]["type"] == experiment_json["filter_object"][1]["type"] + ) + assert ( + test_json[experiment_type]["channels"].lower() + == experiment_json["filter_object"][1]["channels"][0] + ) + assert ( + test_json[experiment_type]["min_version"] + == f"{[item for item in experiment_json['filter_object'][2]['versions']][0]}.0" + ) + assert ( + test_json[experiment_type]["max_version"] + == f"{[item for item in experiment_json['filter_object'][2]['versions']][-1]}.0" + ) + assert ( + test_json[experiment_type]["userFacingName"] + == experiment_json["arguments"]["userFacingName"] + ) + assert ( + test_json[experiment_type]["userFacingDescription"] + == experiment_json["arguments"]["userFacingDescription"] + ) + assert len(test_json[experiment_type]["branches"]) == len( + experiment_json["arguments"]["branches"] + ) + for item in experiment_json["arguments"][ + "branches" + ]: # Loop over each item in the Branches secion + for num in range( + len(experiment_json["arguments"]["branches"]) + ): # Check each branch so we need to do the check for as many branches exis + try: + assert ( + item["slug"] + == test_json[experiment_type]["branches"][num]["branch_name"] + ) + except AssertionError: + continue diff --git a/app/tests/integration/test_overview.py b/app/tests/integration/test_overview.py index 2eb1968065..ded8c05774 100644 --- a/app/tests/integration/test_overview.py +++ b/app/tests/integration/test_overview.py @@ -9,8 +9,8 @@ def test_overview_type_changes_correctly(base_url, selenium): selenium.get(base_url) home = Home(selenium, base_url).wait_for_page_to_load() experiment = home.create_experiment() - assert "pref" in experiment.experiment_type - exp_type = "addon" + assert "Pref-Flip Experiment" in experiment.experiment_type + exp_type = "Add-On Experiment" experiment.experiment_type = exp_type assert exp_type in experiment.experiment_type diff --git a/app/tests/integration/test_single_pref_e2e.py b/app/tests/integration/test_single_pref_e2e.py index a81b821b1c..d447facb26 100644 --- a/app/tests/integration/test_single_pref_e2e.py +++ b/app/tests/integration/test_single_pref_e2e.py @@ -8,6 +8,7 @@ @pytest.mark.use_variables +@pytest.mark.single_pref @pytest.mark.nondestructive def test_single_pref_e2e( base_url,