diff options
Diffstat (limited to 'xt/selenium')
38 files changed, 6544 insertions, 0 deletions
diff --git a/xt/selenium/bug_edit.t b/xt/selenium/bug_edit.t new file mode 100644 index 000000000..46e7e6cb3 --- /dev/null +++ b/xt/selenium/bug_edit.t @@ -0,0 +1,441 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# This Source Code Form is "Incompatible With Secondary Licenses", as +# defined by the Mozilla Public License, v. 2.0. + +use 5.10.1; +use strict; +use warnings; + +use FindBin qw($RealBin); +use lib "$RealBin/../lib"; + +use Test::More "no_plan"; + +use QA::Util; + +my ($sel, $config) = get_selenium(); + +log_in($sel, $config, 'admin'); +set_parameters($sel, { "Bug Fields" => {"usestatuswhiteboard-on" => undef} }); + +# Clear the saved search, in case this test didn't complete previously. +if ($sel->is_text_present("My bugs from QA_Selenium")) { + $sel->click_ok("link=My bugs from QA_Selenium"); + $sel->wait_for_page_to_load_ok(WAIT_TIME); + $sel->title_is("Bug List: My bugs from QA_Selenium"); + $sel->click_ok("forget_search"); + $sel->wait_for_page_to_load_ok(WAIT_TIME); + $sel->title_is("Search is gone"); + $sel->is_text_present_ok("OK, the My bugs from QA_Selenium search is gone"); +} + +# Just in case the test failed before completion previously, reset the CANEDIT bit. +go_to_admin($sel); +$sel->click_ok("link=Groups"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Edit Groups"); +$sel->click_ok("link=Master"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Change Group: Master"); +my $group_url = $sel->get_location(); +$group_url =~ /group=(\d+)$/; +my $master_gid = $1; + +clear_canedit_on_testproduct($sel, $master_gid); +logout($sel); + +# First create a bug. + +log_in($sel, $config, 'QA_Selenium_TEST'); +file_bug_in_product($sel, 'TestProduct'); +my $bug_summary = "Test bug editing"; +$sel->select_ok("bug_severity", "label=critical"); +$sel->type_ok("short_desc", $bug_summary); +$sel->type_ok("comment", "ploc"); +my $bug1_id = create_bug($sel, $bug_summary); + +# Now edit field values of the bug you just filed. + +$sel->select_ok("rep_platform", "label=Other"); +$sel->select_ok("op_sys", "label=Other"); +$sel->select_ok("priority", "label=Highest"); +$sel->select_ok("bug_severity", "label=blocker"); +$sel->type_ok("bug_file_loc", "foo.cgi?action=bar"); +$sel->type_ok("status_whiteboard", "[Selenium was here]"); +$sel->type_ok("comment", "new comment from me :)"); +$sel->select_ok("bug_status", "label=RESOLVED"); +edit_bug($sel, $bug1_id, $bug_summary); + +# Now move the bug into another product, which has a mandatory group. + +$sel->click_ok("link=$bug1_id"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_like(qr/^$bug1_id /); +$sel->select_ok("product", "label=QA-Selenium-TEST"); +$sel->type_ok("comment", "moving to QA-Selenium-TEST"); +$sel->click_ok("commit"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Verify New Product Details..."); +$sel->select_ok("component", "label=QA-Selenium-TEST"); +$sel->is_element_present_ok('//input[@type="checkbox" and @name="groups" and @value="QA-Selenium-TEST"]'); +ok(!$sel->is_editable('//input[@type="checkbox" and @name="groups" and @value="QA-Selenium-TEST"]'), "QA-Selenium-TEST group not editable"); +$sel->is_checked_ok('//input[@type="checkbox" and @name="groups" and @value="QA-Selenium-TEST"]'); +edit_bug_and_return($sel, $bug1_id, $bug_summary, {id => "change_product"}); +$sel->select_ok("bug_severity", "label=normal"); +$sel->select_ok("priority", "label=High"); +$sel->select_ok("rep_platform", "label=All"); +$sel->select_ok("op_sys", "label=All"); +$sel->click_ok("cc_edit_area_showhide"); +$sel->type_ok("newcc", $config->{admin_user_login}); +$sel->type_ok("comment", "Unchecking the reporter_accessible checkbox"); +# This checkbox is checked by default. +$sel->click_ok("reporter_accessible"); +$sel->select_ok("bug_status", "label=VERIFIED"); +edit_bug_and_return($sel, $bug1_id, $bug_summary); +$sel->type_ok("comment", "I am the reporter, but I can see the bug anyway as I belong to the mandatory group"); +edit_bug($sel, $bug1_id, $bug_summary); +logout($sel); + +# The admin is not in the mandatory group, but he has been CC'ed, +# so he can view and edit the bug (as he has editbugs privs by inheritance). + +log_in($sel, $config, 'admin'); +go_to_bug($sel, $bug1_id); +$sel->select_ok("bug_severity", "label=blocker"); +$sel->select_ok("priority", "label=Highest"); +$sel->type_ok("status_whiteboard", "[Selenium was here][admin too]"); +$sel->select_ok("bug_status", "label=CONFIRMED"); +$sel->click_ok("bz_assignee_edit_action"); +$sel->type_ok("assigned_to", $config->{admin_user_login}); +$sel->type_ok("comment", "I have editbugs privs. Taking!"); +edit_bug_and_return($sel, $bug1_id, $bug_summary); +$sel->click_ok("cc_edit_area_showhide"); +$sel->type_ok("newcc", $config->{unprivileged_user_login}); +edit_bug($sel, $bug1_id, $bug_summary); +logout($sel); + +# The powerless user can see the restricted bug, as he has been CC'ed. + +log_in($sel, $config, 'unprivileged'); +go_to_bug($sel, $bug1_id); +$sel->is_text_present_ok("I have editbugs privs. Taking!"); +logout($sel); + +# Now turn off cclist_accessible, which will prevent +# the powerless user to see the bug again. + +log_in($sel, $config, 'admin'); +go_to_bug($sel, $bug1_id); +$sel->click_ok("cclist_accessible"); +$sel->type_ok("comment", "I am allowed to turn off cclist_accessible despite not being in the mandatory group"); +edit_bug($sel, $bug1_id, $bug_summary); +logout($sel); + +# The powerless user cannot see the restricted bug anymore. + +log_in($sel, $config, 'unprivileged'); +$sel->type_ok("quicksearch_top", $bug1_id); +$sel->click_ok("find_top"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Bug Access Denied"); +$sel->is_text_present_ok("You are not authorized to access bug #$bug1_id"); +logout($sel); + +# Move the bug back to TestProduct, which has no group restrictions. + +log_in($sel, $config, 'admin'); +go_to_bug($sel, $bug1_id); +$sel->select_ok("product", "label=TestProduct"); +# When selecting a new product, Bugzilla tries to reassign the bug by default, +# so we have to uncheck it. +$sel->click_ok("set_default_assignee"); +$sel->uncheck_ok("set_default_assignee"); +$sel->type_ok("comment", "-> Moving back to Testproduct."); +$sel->click_ok("commit"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Verify New Product Details..."); +$sel->select_ok("component", "label=TestComponent"); +$sel->is_text_present_ok("These groups are not legal for the 'TestProduct' product or you are not allowed to restrict bugs to these groups"); +$sel->is_element_present_ok('//input[@type="checkbox" and @name="groups" and @value="QA-Selenium-TEST"]'); +ok(!$sel->is_editable('//input[@type="checkbox" and @name="groups" and @value="QA-Selenium-TEST"]'), "QA-Selenium-TEST group not editable"); +ok(!$sel->is_checked('//input[@type="checkbox" and @name="groups" and @value="QA-Selenium-TEST"]'), "QA-Selenium-TEST group not selected"); +$sel->is_element_present_ok('//input[@type="checkbox" and @name="groups" and @value="Master"]'); +$sel->is_editable_ok('//input[@type="checkbox" and @name="groups" and @value="Master"]'); +ok(!$sel->is_checked('//input[@type="checkbox" and @name="groups" and @value="Master"]'), "Master group not selected by default"); +edit_bug($sel, $bug1_id, $bug_summary, {id => "change_product"}); +logout($sel); + +# The unprivileged user can view the bug again, but cannot +# edit it, except adding comments. + +log_in($sel, $config, 'unprivileged'); +go_to_bug($sel, $bug1_id); +$sel->type_ok("comment", "I have no privs, I can only comment (and remove people from the CC list)"); +ok(!$sel->is_element_present('//select[@name="product"]'), "Product field not editable"); +ok(!$sel->is_element_present('//select[@name="bug_severity"]'), "Severity field not editable"); +ok(!$sel->is_element_present('//select[@name="priority"]'), "Priority field not editable"); +ok(!$sel->is_element_present('//select[@name="op_sys"]'), "OS field not editable"); +ok(!$sel->is_element_present('//select[@name="rep_platform"]'), "Hardware field not editable"); +$sel->click_ok("cc_edit_area_showhide"); +$sel->add_selection_ok("cc", "label=" . $config->{admin_user_login}); +$sel->click_ok("removecc"); +edit_bug($sel, $bug1_id, $bug_summary); +logout($sel); + +# Now let's test the CANEDIT bit. + +log_in($sel, $config, 'admin'); +edit_product($sel, "TestProduct"); +$sel->click_ok("link=Edit Group Access Controls:"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Edit Group Controls for TestProduct"); +$sel->check_ok("canedit_$master_gid"); +$sel->click_ok("submit"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Update group access controls for TestProduct"); + +# The user is in the master group, so he can comment. + +go_to_bug($sel, $bug1_id); +$sel->type_ok("comment", "Do nothing except adding a comment..."); +edit_bug($sel, $bug1_id, $bug_summary); +logout($sel); + +# This user is not in the master group, so he cannot comment. + +log_in($sel, $config, 'QA_Selenium_TEST'); +go_to_bug($sel, $bug1_id); +$sel->type_ok("comment", "Just a comment too..."); +$sel->click_ok("commit"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Product Edit Access Denied"); +$sel->is_text_present_ok("You are not permitted to edit bugs in product TestProduct."); +logout($sel); + +# Test searches and "format for printing". + +log_in($sel, $config, 'admin'); +open_advanced_search_page($sel); +$sel->remove_all_selections_ok("product"); +$sel->add_selection_ok("product", "TestProduct"); +$sel->remove_all_selections_ok("bug_status"); +$sel->remove_all_selections_ok("resolution"); +$sel->check_ok("emailassigned_to1"); +$sel->select_ok("emailtype1", "label=is"); +$sel->type_ok("email1", $config->{admin_user_login}); +$sel->check_ok("emailassigned_to2"); +$sel->check_ok("emailqa_contact2"); +$sel->check_ok("emailcc2"); +$sel->select_ok("emailtype2", "label=is"); +$sel->type_ok("email2", $config->{QA_Selenium_TEST_user_login}); +$sel->click_ok("Search"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Bug List"); + +$sel->is_text_present_ok("One bug found."); +$sel->type_ok("save_newqueryname", "My bugs from QA_Selenium"); +$sel->click_ok("remember"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Search created"); +$sel->is_text_present_ok("OK, you have a new search named My bugs from QA_Selenium."); +$sel->click_ok("link=My bugs from QA_Selenium"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Bug List: My bugs from QA_Selenium"); +$sel->click_ok("long_format"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Full Text Bug Listing"); +$sel->is_text_present_ok("Bug $bug1_id"); +$sel->is_text_present_ok("Status: CONFIRMED"); +$sel->is_text_present_ok("Reporter: QA-Selenium-TEST <$config->{QA_Selenium_TEST_user_login}>"); +$sel->is_text_present_ok("Assignee: admin <$config->{admin_user_login}>"); +$sel->is_text_present_ok("Severity: blocker"); +$sel->is_text_present_ok("Priority: Highest"); +$sel->is_text_present_ok("I have no privs, I can only comment"); +logout($sel); + +# Let's create a 2nd bug by this user so that we can test mass-change +# using the saved search the admin just created. + +log_in($sel, $config, 'QA_Selenium_TEST'); +file_bug_in_product($sel, 'TestProduct'); +my $bug_summary2 = "New bug from me"; +$sel->select_ok("bug_severity", "label=blocker"); +$sel->type_ok("short_desc", $bug_summary2); +# We turned on the CANEDIT bit for TestProduct. +$sel->type_ok("comment", "I can enter a new bug, but not edit it, right?"); +my $bug2_id = create_bug($sel, $bug_summary2); + +# Clicking the "Back" button and resubmitting the form again should trigger a warning. + +$sel->go_back_ok(); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Enter Bug: TestProduct"); +$sel->click_ok("commit"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Suspicious Action"); +$sel->is_text_present_ok("no valid token for the create_bug action while processing the 'post_bug.cgi' script"); +$sel->click_ok("confirm"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_like(qr/\d+ \S $bug_summary2/, "Bug created"); +$sel->type_ok("comment", "New comment not allowed"); +$sel->click_ok("commit"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Product Edit Access Denied"); +$sel->is_text_present_ok("You are not permitted to edit bugs in product TestProduct."); +logout($sel); + +# Reassign the newly created bug to the admin. + +log_in($sel, $config, 'admin'); +go_to_bug($sel, $bug2_id); +$sel->click_ok("bz_assignee_edit_action"); +$sel->type_ok("assigned_to", $config->{admin_user_login}); +$sel->type_ok("comment", "Taking!"); +edit_bug($sel, $bug2_id, $bug_summary2); + +# Test mass-change. + +$sel->click_ok("link=My bugs from QA_Selenium"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Bug List: My bugs from QA_Selenium"); +$sel->is_text_present_ok("2 bugs found"); +$sel->click_ok("mass_change"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Bug List"); +$sel->click_ok("check_all"); +$sel->type_ok("comment", 'Mass change"'); +$sel->select_ok("bug_status", "label=RESOLVED"); +$sel->select_ok("resolution", "label=WORKSFORME"); +$sel->click_ok("commit"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Bugs processed"); + +$sel->click_ok("link=$bug1_id"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_like(qr/$bug1_id /); +$sel->selected_label_is("resolution", "WORKSFORME"); +$sel->select_ok("resolution", "label=INVALID"); +edit_bug_and_return($sel, $bug1_id, $bug_summary); +$sel->selected_label_is("resolution", "INVALID"); + +$sel->click_ok("link=History"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Changes made to bug $bug1_id"); +$sel->is_text_present_ok("URL foo.cgi?action=bar"); +$sel->is_text_present_ok("Severity critical blocker"); +$sel->is_text_present_ok("Whiteboard [Selenium was here] [Selenium was here][admin too]"); +$sel->is_text_present_ok("Product QA-Selenium-TEST TestProduct"); +$sel->is_text_present_ok("Status CONFIRMED RESOLVED"); + +# Last step: move bugs to another DB, if the extension is enabled. + +if ($config->{test_extensions}) { + set_parameters($sel, { "Bug Moving" => {"move-to-url" => {type => "text", value => 'http://www.foo.com/'}, + "move-to-address" => {type => "text", value => 'import@foo.com'}, + "movers" => {type => "text", value => $config->{admin_user_login}} + } + }); + + $sel->click_ok("link=My bugs from QA_Selenium"); + $sel->wait_for_page_to_load_ok(WAIT_TIME); + $sel->title_is("Bug List: My bugs from QA_Selenium"); + $sel->is_text_present_ok("2 bugs found"); + $sel->click_ok("mass_change"); + $sel->wait_for_page_to_load_ok(WAIT_TIME); + $sel->title_is("Bug List"); + $sel->click_ok("check_all"); + $sel->type_ok("comment", "-> moved"); + $sel->click_ok('oldbugmove'); + $sel->wait_for_page_to_load_ok(WAIT_TIME); + $sel->title_is("Bugs processed"); + $sel->is_text_present_ok("Changes submitted for bug $bug1_id"); + $sel->is_text_present_ok("Changes submitted for bug $bug2_id"); + $sel->click_ok("link=$bug2_id"); + $sel->wait_for_page_to_load_ok(WAIT_TIME); + $sel->title_like(qr/^$bug2_id/); + $sel->selected_label_is("resolution", "MOVED"); + $sel->is_text_present_ok("Bug moved to http://www.foo.com/."); + + # Disable bug moving again. + set_parameters($sel, { "Bug Moving" => {"movers" => {type => "text", value => ""}} }); +} + +# Make sure token checks are working correctly for single bug editing and mass change, +# first with no token, then with an invalid token. + +foreach my $params (["no_token_single_bug", ""], ["invalid_token_single_bug", "&token=1"]) { + my ($comment, $token) = @$params; + $sel->open_ok("/$config->{bugzilla_installation}/process_bug.cgi?id=$bug1_id&comment=$comment$token", + undef, "Edit a single bug with " . ($token ? "an invalid" : "no") . " token"); + $sel->title_is("Suspicious Action"); + $sel->is_text_present_ok($token ? "an invalid token" : "web browser directly"); + edit_bug_and_return($sel, $bug1_id, $bug_summary, {id => "confirm"}); + $sel->is_text_present_ok($comment); +} + +foreach my $params (["no_token_mass_change", ""], ["invalid_token_mass_change", "&token=1"]) { + my ($comment, $token) = @$params; + $sel->open_ok("/$config->{bugzilla_installation}/process_bug.cgi?id_$bug1_id=1&id_$bug2_id=1&comment=$comment$token", + undef, "Mass change with " . ($token ? "an invalid" : "no") . " token"); + $sel->title_is("Suspicious Action"); + $sel->is_text_present_ok("no valid token for the buglist_mass_change action"); + $sel->click_ok("confirm"); + $sel->wait_for_page_to_load_ok(WAIT_TIME); + $sel->title_is("Bugs processed"); + foreach my $bug_id ($bug1_id, $bug2_id) { + $sel->click_ok("link=$bug_id"); + $sel->wait_for_page_to_load_ok(WAIT_TIME); + $sel->title_like(qr/^$bug_id /); + $sel->is_text_present_ok($comment); + next if $bug_id == $bug2_id; + $sel->go_back_ok(); + $sel->wait_for_page_to_load_ok(WAIT_TIME); + $sel->title_is("Bugs processed"); + } +} + +# Now move these bugs out of our radar. + +$sel->click_ok("link=My bugs from QA_Selenium"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Bug List: My bugs from QA_Selenium"); +$sel->is_text_present_ok("2 bugs found"); +$sel->click_ok("mass_change"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Bug List"); +$sel->click_ok("check_all"); +$sel->type_ok("comment", "Reassigning to the reporter"); +$sel->type_ok("assigned_to", $config->{QA_Selenium_TEST_user_login}); +$sel->click_ok("commit"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Bugs processed"); + +# Now delete the saved search. + +$sel->click_ok("link=My bugs from QA_Selenium"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Bug List: My bugs from QA_Selenium"); +$sel->click_ok("forget_search"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Search is gone"); +$sel->is_text_present_ok("OK, the My bugs from QA_Selenium search is gone"); + +# Reset the CANEDIT bit. We want it to be turned off by default. +clear_canedit_on_testproduct($sel, $master_gid); +logout($sel); + +sub clear_canedit_on_testproduct { + my ($sel, $master_gid) = @_; + + edit_product($sel, "TestProduct"); + $sel->click_ok("link=Edit Group Access Controls:"); + $sel->wait_for_page_to_load_ok(WAIT_TIME); + $sel->title_is("Edit Group Controls for TestProduct"); + $sel->uncheck_ok("canedit_$master_gid"); + $sel->click_ok("submit"); + $sel->wait_for_page_to_load_ok(WAIT_TIME); + $sel->title_is("Update group access controls for TestProduct"); +} diff --git a/xt/selenium/choose_priority.t b/xt/selenium/choose_priority.t new file mode 100644 index 000000000..1089d2003 --- /dev/null +++ b/xt/selenium/choose_priority.t @@ -0,0 +1,30 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# This Source Code Form is "Incompatible With Secondary Licenses", as +# defined by the Mozilla Public License, v. 2.0. + +use 5.10.1; +use strict; +use warnings; + +use FindBin qw($RealBin); +use lib "$RealBin/../lib"; + +use Test::More "no_plan"; + +use QA::Util; + +my ($sel, $config) = get_selenium(); + +log_in($sel, $config, 'admin'); +set_parameters($sel, { "Bug Change Policies" => {"letsubmitterchoosepriority-off" => undef} }); +file_bug_in_product($sel, "TestProduct"); +ok(!$sel->is_text_present("Priority"), "The Priority label is not present"); +ok(!$sel->is_element_present("//select[\@name='priority']"), "The Priority drop-down menu is not present"); +set_parameters($sel, { "Bug Change Policies" => {"letsubmitterchoosepriority-on" => undef} }); +file_bug_in_product($sel, "TestProduct"); +$sel->is_text_present_ok("Priority"); +$sel->is_element_present_ok("//select[\@name='priority']"); +logout($sel); diff --git a/xt/selenium/classifications.t b/xt/selenium/classifications.t new file mode 100644 index 000000000..4d5d012f0 --- /dev/null +++ b/xt/selenium/classifications.t @@ -0,0 +1,142 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# This Source Code Form is "Incompatible With Secondary Licenses", as +# defined by the Mozilla Public License, v. 2.0. + +use 5.10.1; +use strict; +use warnings; + +use FindBin qw($RealBin); +use lib "$RealBin/../lib"; + +use Test::More "no_plan"; + +use QA::Util; + +my ($sel, $config) = get_selenium(); + +# Enable classifications + +log_in($sel, $config, 'admin'); +set_parameters($sel, { "Bug Fields" => {"useclassification-on" => undef} }); + +# Create a new classification. + +go_to_admin($sel); +$sel->click_ok("link=Classifications"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Select classification"); + +# Delete old classifications if this script failed. +# Accessing action=delete directly must 1) trigger the security check page, +# and 2) automatically reclassify products in this classification. +if ($sel->is_text_present("cone")) { + $sel->open_ok("/$config->{bugzilla_installation}/editclassifications.cgi?action=delete&classification=cone"); + $sel->title_is("Suspicious Action"); + $sel->click_ok("confirm"); + $sel->wait_for_page_to_load_ok(WAIT_TIME); + $sel->title_is("Classification Deleted"); +} +if ($sel->is_text_present("ctwo")) { + $sel->open_ok("/$config->{bugzilla_installation}/editclassifications.cgi?action=delete&classification=ctwo"); + $sel->title_is("Suspicious Action"); + $sel->click_ok("confirm"); + $sel->wait_for_page_to_load_ok(WAIT_TIME); + $sel->title_is("Classification Deleted"); +} + +$sel->click_ok("link=Add a new classification"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Add new classification"); +$sel->type_ok("classification", "cone"); +$sel->type_ok("description", "Classification number 1"); +$sel->click_ok('//input[@type="submit" and @value="Add"]'); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("New Classification Created"); + +# Add TestProduct to the new classification. There should be no other +# products in this classification. + +$sel->select_ok("prodlist", "value=TestProduct"); +$sel->click_ok("add_products"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Reclassify products"); +my @products = $sel->get_select_options("myprodlist"); +ok(scalar @products == 1 && $products[0] eq 'TestProduct', "TestProduct successfully added to 'cone'"); + +# Create a new bug in this product/classification. + +file_bug_in_product($sel, 'TestProduct', 'cone'); +my $bug_summary = "Bug in classification cone"; +$sel->type_ok("short_desc", $bug_summary); +$sel->type_ok("comment", "Created by Selenium with classifications turned on"); +create_bug($sel, $bug_summary); + +# Rename 'cone' to 'Unclassified', which must be rejected as it already exists, +# then to 'ctwo', which is not yet in use. Should work fine, even with products +# already in it. + +go_to_admin($sel); +$sel->click_ok("link=Classifications"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Select classification"); +$sel->click_ok("link=cone"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Edit classification"); +$sel->type_ok("classification", "Unclassified"); +$sel->click_ok("//input[\@value='Update']"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Classification Already Exists"); +$sel->go_back_ok(); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Edit classification"); +$sel->type_ok("classification", "ctwo"); +$sel->click_ok("//input[\@value='Update']"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Classification Updated"); + +# Now try to delete the 'ctwo' classification. It should fail as there are +# products in it. + +go_to_admin($sel); +$sel->click_ok("link=Classifications"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Select classification"); +$sel->click_ok('//a[@href="editclassifications.cgi?action=del&classification=ctwo"]'); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Error"); +my $error = trim($sel->get_text("error_msg")); +ok($error =~ /there are products for this classification/, "Reject classification deletion"); + +# Reclassify the product before deleting the classification. + +$sel->go_back_ok(); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Select classification"); +$sel->click_ok('//a[@href="editclassifications.cgi?action=reclassify&classification=ctwo"]'); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Reclassify products"); +$sel->add_selection_ok("myprodlist", "label=TestProduct"); +$sel->click_ok("remove_products"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Reclassify products"); +$sel->click_ok("link=edit"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Select classification"); +$sel->click_ok('//a[@href="editclassifications.cgi?action=del&classification=ctwo"]'); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Delete classification"); +$sel->is_text_present_ok("Do you really want to delete this classification?"); +$sel->click_ok("//input[\@value='Yes, delete']"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Classification Deleted"); + +# Disable classifications and make sure you cannot edit them anymore. + +set_parameters($sel, { "Bug Fields" => {"useclassification-off" => undef} }); +$sel->open_ok("/$config->{bugzilla_installation}/editclassifications.cgi"); +$sel->title_is("Classification Not Enabled"); +logout($sel); diff --git a/xt/selenium/config.t b/xt/selenium/config.t new file mode 100644 index 000000000..b99927321 --- /dev/null +++ b/xt/selenium/config.t @@ -0,0 +1,48 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# This Source Code Form is "Incompatible With Secondary Licenses", as +# defined by the Mozilla Public License, v. 2.0. + +use 5.10.1; +use strict; +use warnings; + +use FindBin qw($RealBin); +use lib "$RealBin/../lib"; + +use Test::More "no_plan"; + +use QA::Util; + +my ($sel, $config) = get_selenium(); + +# Turn on 'requirelogin' and log out. + +log_in($sel, $config, 'admin'); +set_parameters($sel, { "User Authentication" => {"requirelogin-on" => undef} }); +logout($sel); + +# Accessing config.cgi should display no sensitive data. + +$sel->open_ok("/$config->{bugzilla_installation}/config.cgi", undef, "Go to config.cgi (JS format)"); +$sel->is_text_present_ok("var status = [ ];"); +$sel->is_text_present_ok("var status_open = [ ];"); +$sel->is_text_present_ok("var status_closed = [ ];"); +$sel->is_text_present_ok("var resolution = [ ];"); +$sel->is_text_present_ok("var keyword = [ ];"); +$sel->is_text_present_ok("var platform = [ ];"); +$sel->is_text_present_ok("var severity = [ ];"); +$sel->is_text_present_ok("var field = [\n];"); + +ok(!$sel->is_text_present("cf_"), "No custom field displayed"); +ok(!$sel->is_text_present("component["), "No component displayed"); +ok(!$sel->is_text_present("version["), "No version displayed"); +ok(!$sel->is_text_present("target_milestone["), "No target milestone displayed"); + +# Turn on 'requirelogin' and log out. + +log_in($sel, $config, 'admin'); +set_parameters($sel, { "User Authentication" => {"requirelogin-off" => undef} }); +logout($sel); diff --git a/xt/selenium/create_user_accounts.t b/xt/selenium/create_user_accounts.t new file mode 100644 index 000000000..7c71273a6 --- /dev/null +++ b/xt/selenium/create_user_accounts.t @@ -0,0 +1,139 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# This Source Code Form is "Incompatible With Secondary Licenses", as +# defined by the Mozilla Public License, v. 2.0. + +use 5.10.1; +use strict; +use warnings; + +use FindBin qw($RealBin); +use lib "$RealBin/../lib"; + +use Test::More "no_plan"; + +use QA::Util; + +my ($sel, $config) = get_selenium(); + +# Set the email regexp for new bugzilla accounts to end with @bugzilla.test. + +log_in($sel, $config, 'admin'); +set_parameters($sel, { "User Authentication" => {"createemailregexp" => {type => "text", value => '[^@]+@bugzilla\.test$'}} }); +logout($sel); + +# Create a valid account. We need to randomize the login address, because a request +# expires after 3 days only and this test can be executed several times per day. +my $valid_account = 'selenium-' . random_string(10) . '@bugzilla.test'; + +$sel->click_ok("link=Home"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Bugzilla Main Page"); +$sel->is_text_present_ok("Open a New Account"); +$sel->click_ok("link=Open a New Account"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Create a new Bugzilla account"); +$sel->type_ok("login", $valid_account); +$sel->click_ok("send"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Request for new user account '$valid_account' submitted"); +$sel->is_text_present_ok("A confirmation email has been sent"); + +# Try creating the same account again. It's too soon. +$sel->click_ok("link=Home"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Bugzilla Main Page"); +$sel->is_text_present_ok("Open a New Account"); +$sel->click_ok("link=Open a New Account"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Create a new Bugzilla account"); +$sel->type_ok("login", $valid_account); +$sel->click_ok("send"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Too Soon For New Token"); +my $error_msg = trim($sel->get_text("error_msg")); +ok($error_msg =~ /Please wait 10 minutes/, "Too soon for this account"); + +# These accounts do not pass the regexp. +my @accounts = ('test@yahoo.com', 'test@bugzilla.net', 'test@bugzilla.test.com'); +foreach my $account (@accounts) { + $sel->click_ok("link=New Account"); + $sel->wait_for_page_to_load_ok(WAIT_TIME); + $sel->title_is("Create a new Bugzilla account"); + $sel->type_ok("login", $account); + $sel->click_ok("send"); + $sel->wait_for_page_to_load_ok(WAIT_TIME); + $sel->title_is("Account Creation Restricted"); + $sel->is_text_present_ok("User account creation has been restricted."); +} + +# These accounts are illegal. +@accounts = ('test\bugzilla@bugzilla.test', 'test@bugzilla.org@bugzilla.test', 'test@bugzilla..test'); +# Logins larger than 127 characters must be rejected, for security reasons. +push @accounts, 'selenium-' . random_string(110) . '@bugzilla.test'; + +foreach my $account (@accounts) { + $sel->click_ok("link=New Account"); + $sel->wait_for_page_to_load_ok(WAIT_TIME); + $sel->title_is("Create a new Bugzilla account"); + # Starting with 5.0, the login field is a type=email and is marked "required" + # This means that we need to add the novalidate attribute to the enclosing form + # so that the illegal login can still be checked by the backend code. + my $script = q{ + document.getElementById('account_creation_form').setAttribute('novalidate', 1); + }; + $sel->run_script($script); + $sel->type_ok("login", $account); + $sel->click_ok("send"); + $sel->wait_for_page_to_load_ok(WAIT_TIME); + $sel->title_is("Invalid Email Address"); + my $error_msg = trim($sel->get_text("error_msg")); + ok($error_msg =~ /^The e-mail address you entered (\S+) didn't pass our syntax checking/, "Invalid email address detected"); +} + +# This account already exists. +$sel->click_ok("link=New Account"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Create a new Bugzilla account"); +$sel->type_ok("login", $config->{admin_user_login}); +$sel->click_ok("send"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Account Already Exists"); +$error_msg = trim($sel->get_text("error_msg")); +ok($error_msg eq "There is already an account with the login name $config->{admin_user_login}.", "Account already exists"); + +# Turn off user account creation. +log_in($sel, $config, 'admin'); +set_parameters($sel, { "User Authentication" => {"createemailregexp" => {type => "text", value => ''}} }); +logout($sel); + +# Make sure that links pointing to createaccount.cgi are all deactivated. +ok(!$sel->is_text_present("New Account"), "No link named 'New Account'"); +$sel->click_ok("link=Home"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Bugzilla Main Page"); +ok(!$sel->is_text_present("Open a New Account"), "No link named 'Open a New Account'"); +$sel->open_ok("/$config->{bugzilla_installation}/createaccount.cgi"); +$sel->title_is("Account Creation Disabled"); +$error_msg = trim($sel->get_text("error_msg")); +ok($error_msg =~ /^User account creation has been disabled. New accounts must be created by an administrator/, + "User account creation disabled"); + +# Re-enable user account creation. + +log_in($sel, $config, 'admin'); +set_parameters($sel, { "User Authentication" => {"createemailregexp" => {type => "text", value => '.*'}} }); + +# Make sure selenium-<random_string>@bugzilla.test has not be added to the DB yet. +go_to_admin($sel); +$sel->click_ok("link=Users"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Search users"); +$sel->type_ok("matchstr", $valid_account); +$sel->click_ok("search"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Select user"); +$sel->is_text_present_ok("0 users found"); +logout($sel); diff --git a/xt/selenium/custom_fields.t b/xt/selenium/custom_fields.t new file mode 100644 index 000000000..6c0c8fa5d --- /dev/null +++ b/xt/selenium/custom_fields.t @@ -0,0 +1,462 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# This Source Code Form is "Incompatible With Secondary Licenses", as +# defined by the Mozilla Public License, v. 2.0. + +use 5.10.1; +use strict; +use warnings; + +use FindBin qw($RealBin); +use lib "$RealBin/../lib"; + +use Test::More "no_plan"; + +use QA::Util; + +my ($sel, $config) = get_selenium(); +log_in($sel, $config, 'admin'); + +# Create new bug to test custom fields + +file_bug_in_product($sel, 'TestProduct'); +my $bug_summary = "What's your ID?"; +$sel->type_ok("short_desc", $bug_summary); +$sel->type_ok("comment", "Use the ID of this bug to generate a unique custom field name."); +$sel->type_ok("bug_severity", "label=normal"); +my $bug1_id = create_bug($sel, $bug_summary); + +# Create custom fields + +go_to_admin($sel); +$sel->click_ok("link=Custom Fields"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Custom Fields"); +$sel->click_ok("link=Add a new custom field"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Add a new Custom Field"); +$sel->type_ok("name", "cf_qa_freetext_$bug1_id"); +$sel->type_ok("desc", "Freetext$bug1_id"); +$sel->select_ok("type", "label=Free Text"); +$sel->type_ok("sortkey", $bug1_id); +# These values are off by default. +$sel->value_is("enter_bug", "off"); +$sel->value_is("obsolete", "off"); +$sel->click_ok("create"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Custom Field Created"); +$sel->is_text_present_ok("The new custom field 'cf_qa_freetext_$bug1_id' has been successfully created."); + +$sel->click_ok("link=Add a new custom field"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Add a new Custom Field"); +$sel->type_ok("name", "cf_qa_list_$bug1_id"); +$sel->type_ok("desc", "List$bug1_id"); +$sel->select_ok("type", "label=Drop Down"); +$sel->type_ok("sortkey", $bug1_id); +$sel->click_ok("enter_bug"); +$sel->value_is("enter_bug", "on"); +$sel->click_ok("new_bugmail"); +$sel->value_is("new_bugmail", "on"); +$sel->value_is("obsolete", "off"); +$sel->click_ok("create"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Custom Field Created"); +$sel->is_text_present_ok("The new custom field 'cf_qa_list_$bug1_id' has been successfully created."); + +$sel->click_ok("link=Add a new custom field"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Add a new Custom Field"); +$sel->type_ok("name", "cf_qa_bugid_$bug1_id"); +$sel->type_ok("desc", "Reference$bug1_id"); +$sel->select_ok("type", "label=Bug ID"); +$sel->type_ok("sortkey", $bug1_id); +$sel->type_ok("reverse_desc", "IsRef$bug1_id"); +$sel->click_ok("enter_bug"); +$sel->value_is("enter_bug", "on"); +$sel->value_is("obsolete", "off"); +$sel->click_ok("create"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Custom Field Created"); +$sel->is_text_present_ok("The new custom field 'cf_qa_bugid_$bug1_id' has been successfully created."); + +# Add values to the custom fields. + +$sel->click_ok("link=cf_qa_list_$bug1_id"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Edit the Custom Field 'cf_qa_list_$bug1_id' (List$bug1_id)"); +$sel->click_ok("link=Edit legal values for this field"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Select value for the 'List$bug1_id' (cf_qa_list_$bug1_id) field"); + +$sel->click_ok("link=Add"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Add Value for the 'List$bug1_id' (cf_qa_list_$bug1_id) field"); +$sel->type_ok("value", "have fun?"); +$sel->type_ok("sortkey", "805"); +$sel->click_ok("create"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("New Field Value Created"); +$sel->is_text_present_ok("The value have fun? has been added as a valid choice for the List$bug1_id (cf_qa_list_$bug1_id) field."); + +$sel->click_ok("link=Add"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Add Value for the 'List$bug1_id' (cf_qa_list_$bug1_id) field"); +$sel->type_ok("value", "storage"); +$sel->type_ok("sortkey", "49"); +$sel->click_ok("create"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("New Field Value Created"); +$sel->is_text_present_ok("The value storage has been added as a valid choice for the List$bug1_id (cf_qa_list_$bug1_id) field."); + +# Also create a new bug status and a new resolution. + +go_to_admin($sel); +$sel->click_ok("link=Field Values"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Edit values for which field?"); +$sel->click_ok("link=Resolution"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Select value for the 'Resolution' (resolution) field"); +$sel->click_ok("link=Add"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Add Value for the 'Resolution' (resolution) field"); +$sel->type_ok("value", "UPSTREAM"); +$sel->type_ok("sortkey", 450); +$sel->click_ok("create"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("New Field Value Created"); + +go_to_admin($sel); +$sel->click_ok("link=Field Values"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Edit values for which field?"); +$sel->click_ok("link=Status"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Select value for the 'Status' (bug_status) field"); +$sel->click_ok("link=Add"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Add Value for the 'Status' (bug_status) field"); +$sel->type_ok("value", "SUSPENDED"); +$sel->type_ok("sortkey", 250); +$sel->click_ok("open_status"); +$sel->click_ok("create"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("New Field Value Created"); + +$sel->click_ok("link=Add"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Add Value for the 'Status' (bug_status) field"); +$sel->type_ok("value", "IN_QA"); +$sel->type_ok("sortkey", 550); +$sel->click_ok("closed_status"); +$sel->click_ok("create"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("New Field Value Created"); + +$sel->click_ok("link=status workflow page"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Edit Workflow"); +$sel->click_ok('//td[@title="From UNCONFIRMED to SUSPENDED"]//input[@type="checkbox"]'); +$sel->click_ok('//td[@title="From CONFIRMED to SUSPENDED"]//input[@type="checkbox"]'); +$sel->click_ok('//td[@title="From SUSPENDED to CONFIRMED"]//input[@type="checkbox"]'); +$sel->click_ok('//td[@title="From SUSPENDED to IN_PROGRESS"]//input[@type="checkbox"]'); +$sel->click_ok('//td[@title="From RESOLVED to IN_QA"]//input[@type="checkbox"]'); +$sel->click_ok('//td[@title="From IN_QA to VERIFIED"]//input[@type="checkbox"]'); +$sel->click_ok('//td[@title="From IN_QA to CONFIRMED"]//input[@type="checkbox"]'); +$sel->click_ok('//input[@value="Commit Changes"]'); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Edit Workflow"); + +# Create new bug to test custom fields in bug creation page + +file_bug_in_product($sel, 'TestProduct'); +$sel->is_text_present_ok("List$bug1_id:"); +$sel->is_element_present_ok("cf_qa_list_$bug1_id"); +$sel->is_text_present_ok("Reference$bug1_id:"); +$sel->is_element_present_ok("cf_qa_bugid_$bug1_id"); +ok(!$sel->is_text_present("Freetext$bug1_id:"), "Freetext$bug1_id is not displayed"); +ok(!$sel->is_element_present("cf_qa_freetext_$bug1_id"), "cf_qa_freetext_$bug1_id is not available"); +my $bug_summary2 = "Et de un"; +$sel->type_ok("short_desc", $bug_summary2); +$sel->select_ok("bug_severity", "critical"); +$sel->type_ok("cf_qa_bugid_$bug1_id", $bug1_id); +my $bug2_id = create_bug($sel, $bug_summary2); + +# Both fields are editable. + +$sel->type_ok("cf_qa_freetext_$bug1_id", "bonsai"); +$sel->selected_label_is("cf_qa_list_$bug1_id", "---"); +$sel->select_ok("bug_status", "label=SUSPENDED"); +edit_bug($sel, $bug2_id, $bug_summary2); + +go_to_bug($sel, $bug1_id); +$sel->type_ok("cf_qa_freetext_$bug1_id", "dumbo"); +$sel->select_ok("cf_qa_list_$bug1_id", "label=storage"); +$sel->is_text_present_ok("IsRef$bug1_id: $bug2_id"); +$sel->select_ok("bug_status", "RESOLVED"); +$sel->select_ok("resolution", "UPSTREAM"); +edit_bug_and_return($sel, $bug1_id, $bug_summary); +$sel->select_ok("bug_status", "IN_QA"); +edit_bug_and_return($sel, $bug1_id, $bug_summary); + +$sel->click_ok("link=Format For Printing"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Full Text Bug Listing"); +$sel->is_text_present_ok("Freetext$bug1_id: dumbo"); +$sel->is_text_present_ok("List$bug1_id: storage"); +$sel->is_text_present_ok("Status: IN_QA UPSTREAM"); +go_to_bug($sel, $bug2_id); +$sel->select_ok("cf_qa_list_$bug1_id", "label=storage"); +edit_bug($sel, $bug2_id, $bug_summary2); + +# Test searching for bugs using the custom fields + +open_advanced_search_page($sel); +$sel->remove_all_selections_ok("product"); +$sel->add_selection_ok("product", "TestProduct"); +$sel->remove_all_selections("bug_status"); +$sel->remove_all_selections("resolution"); +$sel->select_ok("f1", "label=List$bug1_id"); +$sel->select_ok("o1", "label=is equal to"); +$sel->type_ok("v1", "storage"); +$sel->click_ok("Search"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Bug List"); +$sel->is_text_present_ok("2 bugs found"); +$sel->is_text_present_ok("What's your ID?"); +$sel->is_text_present_ok("Et de un"); + +# Now edit custom fields in mass changes. + +$sel->click_ok("mass_change"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Bug List"); +$sel->click_ok("check_all"); +$sel->select_ok("cf_qa_list_$bug1_id", "label=---"); +$sel->type_ok("cf_qa_freetext_$bug1_id", "thanks"); +$sel->click_ok("commit"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Bugs processed"); +$sel->click_ok("link=$bug2_id"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_like(qr/^$bug2_id/); +$sel->value_is("cf_qa_freetext_$bug1_id", "thanks"); +$sel->selected_label_is("cf_qa_list_$bug1_id", "---"); +$sel->select_ok("cf_qa_list_$bug1_id", "label=storage"); +edit_bug($sel, $bug2_id, $bug_summary2); + +# Let's now test custom field visibility. + +go_to_admin($sel); +$sel->click_ok("link=Custom Fields"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Custom Fields"); +$sel->click_ok("link=cf_qa_list_$bug1_id"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Edit the Custom Field 'cf_qa_list_$bug1_id' (List$bug1_id)"); +$sel->select_ok("visibility_field_id", "label=Severity (bug_severity)"); +$sel->add_selection_ok("visibility_values", "label=blocker"); +$sel->add_selection_ok("visibility_values", "label=critical"); +$sel->click_ok("edit"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Custom Field Updated"); + +go_to_bug($sel, $bug1_id); +$sel->is_element_present_ok("cf_qa_list_$bug1_id", "List$bug1_id is in the DOM of the page..."); +ok(!$sel->is_visible("cf_qa_list_$bug1_id"), "... but is not displayed with severity = 'normal'"); +$sel->select_ok("bug_severity", "major"); +ok(!$sel->is_visible("cf_qa_list_$bug1_id"), "... nor with severity = 'major'"); +$sel->select_ok("bug_severity", "critical"); +$sel->is_visible_ok("cf_qa_list_$bug1_id", "... but is visible with severity = 'critical'"); +edit_bug_and_return($sel, $bug1_id, $bug_summary); +$sel->is_visible_ok("cf_qa_list_$bug1_id"); + +go_to_bug($sel, $bug2_id); +$sel->is_visible_ok("cf_qa_list_$bug1_id"); +$sel->select_ok("bug_severity", "minor"); +ok(!$sel->is_visible("cf_qa_list_$bug1_id"), "List$bug1_id is not displayed with severity = 'minor'"); +edit_bug_and_return($sel, $bug2_id, $bug_summary2); +ok(!$sel->is_visible("cf_qa_list_$bug1_id"), "List$bug1_id is not displayed with severity = 'minor'"); + +# Add a new value which is only listed under some condition. + +go_to_admin($sel); +$sel->click_ok("link=Custom Fields"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Custom Fields"); +$sel->click_ok("link=cf_qa_list_$bug1_id"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Edit the Custom Field 'cf_qa_list_$bug1_id' (List$bug1_id)"); +$sel->select_ok("value_field_id", "label=Resolution (resolution)"); +$sel->click_ok("edit"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Custom Field Updated"); +$sel->click_ok("link=cf_qa_list_$bug1_id"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Edit the Custom Field 'cf_qa_list_$bug1_id' (List$bug1_id)"); +$sel->click_ok("link=Edit legal values for this field"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Select value for the 'List$bug1_id' (cf_qa_list_$bug1_id) field"); +$sel->click_ok("link=Add"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Add Value for the 'List$bug1_id' (cf_qa_list_$bug1_id) field"); +$sel->type_ok("value", "ghost"); +$sel->type_ok("sortkey", "500"); +$sel->select_ok("visibility_value_id", "label=FIXED"); +$sel->click_ok("id=create"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("New Field Value Created"); + +go_to_bug($sel, $bug1_id); +my @labels = $sel->get_select_options("cf_qa_list_$bug1_id"); +ok(grep(/^ghost$/, @labels), "ghost is in the DOM of the page..."); +my $disabled = $sel->get_attribute("v4_cf_qa_list_$bug1_id\@disabled"); +ok($disabled, "... but is not available for selection by default"); +$sel->select_ok("bug_status", "label=RESOLVED"); +$sel->select_ok("resolution", "label=FIXED"); +$sel->select_ok("cf_qa_list_$bug1_id", "label=ghost"); +edit_bug_and_return($sel, $bug1_id, $bug_summary); +$sel->selected_label_is("cf_qa_list_$bug1_id", "ghost"); + +# Delete an unused field value. + +go_to_admin($sel); +$sel->click_ok("link=Field Values"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Edit values for which field?"); +$sel->click_ok("link=List$bug1_id"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Select value for the 'List$bug1_id' (cf_qa_list_$bug1_id) field"); +$sel->click_ok("//a[contains(\@href, 'editvalues.cgi?action=del&field=cf_qa_list_$bug1_id&value=have%20fun%3F')]"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Delete Value 'have fun?' from the 'List$bug1_id' (cf_qa_list_$bug1_id) field"); +$sel->is_text_present_ok("Do you really want to delete this value?"); +$sel->click_ok("delete"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Field Value Deleted"); + +# This value cannot be deleted as it's in use. + +$sel->click_ok("//a[contains(\@href, 'editvalues.cgi?action=del&field=cf_qa_list_$bug1_id&value=storage')]"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Delete Value 'storage' from the 'List$bug1_id' (cf_qa_list_$bug1_id) field"); +$sel->is_text_present_ok("There is 1 bug with this field value"); + +# Mark the <select> field as obsolete, making it unavailable in bug reports. + +go_to_admin($sel); +$sel->click_ok("link=Custom Fields"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Custom Fields"); +$sel->click_ok("link=cf_qa_list_$bug1_id"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Edit the Custom Field 'cf_qa_list_$bug1_id' (List$bug1_id)"); +$sel->click_ok("obsolete"); +$sel->value_is("obsolete", "on"); +$sel->click_ok("edit"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Custom Field Updated"); +go_to_bug($sel, $bug1_id); +$sel->value_is("cf_qa_freetext_$bug1_id", "thanks"); +ok(!$sel->is_element_present("cf_qa_list_$bug1_id"), "The custom list is not visible"); + +# Custom fields are also viewable by logged out users. + +logout($sel); +go_to_bug($sel, $bug1_id); +$sel->is_text_present_ok("Freetext$bug1_id: thanks"); + +# Powerless users should still be able to CC themselves when +# custom fields are in use. + +log_in($sel, $config, 'unprivileged'); +go_to_bug($sel, $bug1_id); +$sel->is_text_present_ok("Freetext$bug1_id: thanks"); +$sel->click_ok("cc_edit_area_showhide"); +$sel->type_ok("newcc", $config->{unprivileged_user_login}); +edit_bug($sel, $bug1_id, $bug_summary); +logout($sel); + +# Disable the remaining free text field. + +log_in($sel, $config, 'admin'); +go_to_admin($sel); +$sel->click_ok("link=Custom Fields"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Custom Fields"); +$sel->click_ok("link=cf_qa_freetext_$bug1_id"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Edit the Custom Field 'cf_qa_freetext_$bug1_id' (Freetext$bug1_id)"); +$sel->click_ok("obsolete"); +$sel->value_is("obsolete", "on"); +$sel->click_ok("edit"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Custom Field Updated"); + +# Trying to delete a bug status which is in use is forbidden. + +go_to_admin($sel); +$sel->click_ok("link=Field Values"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Edit values for which field?"); +$sel->click_ok("link=Status"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Select value for the 'Status' (bug_status) field"); +$sel->click_ok('//a[@href="editvalues.cgi?action=del&field=bug_status&value=SUSPENDED"]'); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Delete Value 'SUSPENDED' from the 'Status' (bug_status) field"); +$sel->is_text_present_ok("Sorry, but the 'SUSPENDED' value cannot be deleted"); + +go_to_bug($sel, $bug2_id); +$sel->select_ok("bug_status", "CONFIRMED"); +edit_bug($sel, $bug2_id, $bug_summary2); + +go_to_bug($sel, $bug1_id); +$sel->select_ok("bug_status", "VERIFIED"); +$sel->select_ok("resolution", "INVALID"); +edit_bug($sel, $bug1_id, $bug_summary); + +# Unused values can be deleted. + +go_to_admin($sel); +$sel->click_ok("link=Field Values"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Edit values for which field?"); +$sel->click_ok("link=Status"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Select value for the 'Status' (bug_status) field"); +$sel->click_ok('//a[@href="editvalues.cgi?action=del&field=bug_status&value=SUSPENDED"]'); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Delete Value 'SUSPENDED' from the 'Status' (bug_status) field"); +$sel->click_ok("delete"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Field Value Deleted"); +$sel->is_text_present_ok("The value SUSPENDED of the Status (bug_status) field has been deleted"); + +$sel->click_ok('//a[@href="editvalues.cgi?action=del&field=bug_status&value=IN_QA"]'); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Delete Value 'IN_QA' from the 'Status' (bug_status) field"); +$sel->click_ok("delete"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Field Value Deleted"); +$sel->is_text_present_ok("The value IN_QA of the Status (bug_status) field has been deleted"); + +go_to_admin($sel); +$sel->click_ok("link=Field Values"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Edit values for which field?"); +$sel->click_ok("link=Resolution"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Select value for the 'Resolution' (resolution) field"); +$sel->click_ok('//a[@href="editvalues.cgi?action=del&field=resolution&value=UPSTREAM"]'); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Delete Value 'UPSTREAM' from the 'Resolution' (resolution) field"); +$sel->click_ok("delete"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Field Value Deleted"); +$sel->is_text_present_ok("The value UPSTREAM of the Resolution (resolution) field has been deleted"); + +logout($sel); diff --git a/xt/selenium/custom_fields_admin.t b/xt/selenium/custom_fields_admin.t new file mode 100644 index 000000000..d0ffb9db8 --- /dev/null +++ b/xt/selenium/custom_fields_admin.t @@ -0,0 +1,56 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# This Source Code Form is "Incompatible With Secondary Licenses", as +# defined by the Mozilla Public License, v. 2.0. + +use 5.10.1; +use strict; +use warnings; + +use FindBin qw($RealBin); +use lib "$RealBin/../lib"; + +use Test::More "no_plan"; + +use QA::Util; + +my ($sel, $config) = get_selenium(); +log_in($sel, $config, 'admin'); + +# Create a custom field, going through each type available, +# mark it as obsolete and delete it immediately. + +go_to_admin($sel); +$sel->click_ok("link=Custom Fields"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Custom Fields"); + +my @types = ("Bug ID", "Large Text Box", "Free Text", "Multiple-Selection Box", + "Drop Down", "Date/Time"); +my $counter = int(rand(10000)); + +foreach my $type (@types) { + my $fname = "cf_field" . ++$counter; + my $fdesc = "Field" . $counter; + + $sel->click_ok("link=Add a new custom field"); + $sel->wait_for_page_to_load_ok(WAIT_TIME); + $sel->title_is("Add a new Custom Field"); + $sel->type_ok("name", $fname); + $sel->type_ok("desc", $fdesc); + $sel->select_ok("type", "label=$type"); + $sel->click_ok("obsolete"); + $sel->click_ok("create"); + $sel->wait_for_page_to_load_ok(WAIT_TIME); + $sel->title_is("Custom Field Created"); + $sel->click_ok("//a[\@href='editfields.cgi?action=del&name=$fname']"); + $sel->wait_for_page_to_load_ok(WAIT_TIME); + $sel->title_is("Delete the Custom Field '$fname' ($fdesc)"); + $sel->click_ok("link=Delete field '$fdesc'"); + $sel->wait_for_page_to_load_ok(WAIT_TIME); + $sel->title_is("Custom Field Deleted"); +} + +logout($sel); diff --git a/xt/selenium/dependencies.t b/xt/selenium/dependencies.t new file mode 100644 index 000000000..133e17e07 --- /dev/null +++ b/xt/selenium/dependencies.t @@ -0,0 +1,56 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# This Source Code Form is "Incompatible With Secondary Licenses", as +# defined by the Mozilla Public License, v. 2.0. + +use 5.10.1; +use strict; +use warnings; + +use FindBin qw($RealBin); +use lib "$RealBin/../lib"; + +use Test::More "no_plan"; + +use QA::Util; + +my ($sel, $config) = get_selenium(); + +# Let's create a public and a private bug. + +log_in($sel, $config, 'admin'); +file_bug_in_product($sel, "TestProduct"); +my $bug_summary = "Dependency Checks"; +$sel->type_ok("short_desc", $bug_summary); +$sel->type_ok("comment", "This bug is public"); +my $bug1_id = create_bug($sel, $bug_summary); + +file_bug_in_product($sel, "TestProduct"); +$sel->type_ok("alias", "secret_qa_bug_$bug1_id+1"); +my $bug_summary2 = "Big Ben"; +$sel->type_ok("short_desc", $bug_summary2); +$sel->type_ok("comment", "This bug is private"); +$sel->type_ok("dependson", $bug1_id); +$sel->check_ok('//input[@name="groups" and @value="Master"]'); +my $bug2_id = create_bug($sel, $bug_summary2); + +go_to_bug($sel, $bug1_id); +$sel->click_ok("link=Mark as Duplicate"); +$sel->type_ok("dup_id", $bug2_id); +edit_bug_and_return($sel, $bug1_id, $bug_summary); +$sel->is_text_present_ok("secret_qa_bug_$bug1_id+1"); +logout($sel); + +# A user with editbugs privs who cannot see some bugs in the dependency list +# or the bug this duplicate points to should still be able to edit this bug. + +log_in($sel, $config, 'editbugs'); +go_to_bug($sel, $bug1_id); +ok(!$sel->is_text_present("secret_qa_bug_$bug1_id+1"), "The alias of the private bug is not visible"); +$sel->select_ok("priority", "label=High"); +$sel->select_ok("bug_status", "VERIFIED"); +$sel->type_ok("comment", "Can I still edit this bug?"); +edit_bug($sel, $bug1_id, $bug_summary); +logout($sel); diff --git a/xt/selenium/edit_products_properties.t b/xt/selenium/edit_products_properties.t new file mode 100644 index 000000000..1f9851729 --- /dev/null +++ b/xt/selenium/edit_products_properties.t @@ -0,0 +1,338 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# This Source Code Form is "Incompatible With Secondary Licenses", as +# defined by the Mozilla Public License, v. 2.0. + +use 5.10.1; +use strict; +use warnings; + +use FindBin qw($RealBin); +use lib "$RealBin/../lib"; + +use Test::More "no_plan"; + +use QA::Util; + +my ($sel, $config) = get_selenium(); + +my $admin_user_login = $config->{admin_user_login}; +my $unprivileged_user_login = $config->{unprivileged_user_login}; +my $permanent_user = $config->{permanent_user}; + +log_in($sel, $config, 'admin'); +set_parameters($sel, { "Bug Fields" => {"useclassification-off" => undef, + "usetargetmilestone-on" => undef}, + "Administrative Policies" => {"allowbugdeletion-on" => undef} + }); + +# Create a product and add components to it. Do some cleanup first +# if the script failed during a previous run. + +go_to_admin($sel); +$sel->click_ok("link=Products"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +# No risk to get the "Select classification" page. We turned off useclassification. +$sel->title_is("Select product"); + +my $text = trim($sel->get_text("bugzilla-body")); +if ($text =~ /(Kill me!|Kill me nicely)/) { + my $product = $1; + my $escaped_product = url_quote($product); + $sel->click_ok("//a[\@href='editproducts.cgi?action=del&product=$escaped_product']"); + $sel->wait_for_page_to_load_ok(WAIT_TIME); + $sel->title_is("Delete Product '$product'"); + $sel->click_ok("delete"); + $sel->wait_for_page_to_load_ok(WAIT_TIME); + $sel->title_is("Product Deleted"); +} + +$sel->click_ok("link=Add"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Add Product"); +$sel->type_ok("product", "Kill me!"); +$sel->type_ok("description", "I will disappear very soon. Do not add bugs to it."); +$sel->type_ok("defaultmilestone", "0.1a"); +# Since Bugzilla 4.0, the voting system is in an extension. +if ($config->{test_extensions}) { + $sel->type_ok("votesperuser", "1"); + $sel->type_ok("maxvotesperbug", "1"); + $sel->type_ok("votestoconfirm", "10"); +} +$sel->type_ok("version", "0.1a"); +$sel->type_ok("component", "first comp"); +$sel->type_ok("comp_desc", "comp 1"); +$sel->type_ok("initialowner", $admin_user_login); +$sel->click_ok("add-product"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Product Created"); + +# Try creating a second component with the same name. + +$sel->click_ok("link=Edit components:"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Select component of product 'Kill me!'"); +$sel->click_ok("link=Add"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Add component to the Kill me! product"); +$sel->type_ok("component", "first comp"); +$sel->type_ok("description", "comp 2"); +$sel->type_ok("initialowner", $admin_user_login); +$sel->click_ok("create"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Component Already Exists"); + +# Now really create a second component, with a distinct name. + +$sel->go_back_ok(); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->type_ok("component", "second comp"); +# FIXME - Re-enter the default assignee (regression due to bug 577574) +$sel->type_ok("initialowner", $admin_user_login); +$sel->type_ok("initialcc", $permanent_user); +$sel->click_ok("create"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Component Created"); + +# Add a new version. + +edit_product($sel, "Kill me!"); +$sel->click_ok("link=Edit versions:"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Select version of product 'Kill me!'"); +$sel->click_ok("link=Add"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->type_ok("version", "0.1"); +$sel->click_ok("create"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Version Created"); + +# Add a new milestone. + +$sel->click_ok("link='Kill me!'"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Edit Product 'Kill me!'"); +$sel->click_ok("link=Edit milestones:"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Select milestone of product 'Kill me!'"); +$sel->click_ok("link=Add"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Add Milestone to Product 'Kill me!'"); +$sel->type_ok("milestone", "0.2"); +$sel->type_ok("sortkey", "2"); +$sel->click_ok("create"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Milestone Created"); + +# Add another milestone. + +$sel->click_ok("link=Add"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Add Milestone to Product 'Kill me!'"); +$sel->type_ok("milestone", "0.1a"); +# Negative sortkeys are valid for milestones. +$sel->type_ok("sortkey", "-2"); +$sel->click_ok("create"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Milestone Already Exists"); +$sel->go_back_ok(); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->type_ok("milestone", "pre-0.1"); +$sel->click_ok("create"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Milestone Created"); + +# Now create an UNCONFIRMED bug and add it to the newly created product. + +file_bug_in_product($sel, "Kill me!"); +$sel->select_ok("version", "label=0.1a"); +$sel->select_ok("component", "label=first comp"); +# UNCONFIRMED must be present. +$sel->select_ok("bug_status", "label=UNCONFIRMED"); +$sel->type_ok("cc", $unprivileged_user_login); +$sel->type_ok("bug_file_loc", "http://www.test.com"); +my $bug_summary = "test create/edit product properties"; +$sel->type_ok("short_desc", $bug_summary); +$sel->type_ok("comment", "this bug will soon be dead"); +my $bug1_id = create_bug($sel, $bug_summary); +my @cc_list = $sel->get_select_options("cc"); +ok(grep($_ eq $unprivileged_user_login, @cc_list), "$unprivileged_user_login correctly added to the CC list"); +ok(!grep($_ eq $permanent_user, @cc_list), "$permanent_user not in the CC list for 'first comp' by default"); + +# File a second bug, and make sure users in the default CC list are added. +file_bug_in_product($sel, "Kill me!"); +$sel->select_ok("version", "label=0.1a"); +$sel->select_ok("component", "label=second comp"); +my $bug_summary2 = "check default CC list"; +$sel->type_ok("short_desc", $bug_summary2); +$sel->type_ok("comment", "is the CC list populated correctly?"); +create_bug($sel, $bug_summary2); +@cc_list = $sel->get_select_options("cc"); +ok(grep($_ eq $permanent_user, @cc_list), "$permanent_user in the CC list for 'second comp' by default"); + +# Edit product properties and set votes_to_confirm to 0, which has +# the side-effect to disable auto-confirmation (new behavior compared +# to Bugzilla 3.4 and older). + +edit_product($sel, "Kill me!"); +$sel->type_ok("product", "Kill me nicely"); +$sel->type_ok("description", "I will disappear very soon. Do not add bugs to it (except for testing)."); +$sel->select_ok("defaultmilestone", "label=0.2"); +if ($config->{test_extensions}) { + $sel->type_ok("votesperuser", "2"); + $sel->type_ok("maxvotesperbug", 5); + $sel->type_ok("votestoconfirm", "0"); +} +$sel->click_ok("update-product"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Updating Product 'Kill me nicely'"); +$sel->is_text_present_ok("Updated product name from 'Kill me!' to 'Kill me nicely'"); +$sel->is_text_present_ok("Updated description"); +$sel->is_text_present_ok("Updated default milestone"); +if ($config->{test_extensions}) { + $sel->is_text_present_ok("Updated votes per user"); + $sel->is_text_present_ok("Updated maximum votes per bug"); + $sel->is_text_present_ok("Updated number of votes needed to confirm a bug"); + $text = trim($sel->get_text("bugzilla-body")); + # We use .{1} in place of the right arrow character, which fails otherwise. + ok($text =~ /Checking unconfirmed bugs in this product for any which now have sufficient votes\.{3} .{1}there were none/, + "No bugs confirmed by popular votes (votestoconfirm = 0 disables auto-confirmation)"); + + # Now set votestoconfirm to 2, vote for a bug, and then set + # this attribute back to 1, to trigger auto-confirmation. + + $sel->click_ok("link=Kill me nicely"); + $sel->wait_for_page_to_load_ok(WAIT_TIME); + $sel->title_is("Edit Product 'Kill me nicely'", "Display properties of Kill me nicely"); + $sel->type_ok("votestoconfirm", 2); + $sel->click_ok("update-product"); + $sel->wait_for_page_to_load_ok(WAIT_TIME); + $sel->title_is("Updating Product 'Kill me nicely'"); + $sel->is_text_present_ok("Updated number of votes needed to confirm a bug"); + + go_to_bug($sel, $bug1_id); + $sel->click_ok("link=vote"); + $sel->wait_for_page_to_load_ok(WAIT_TIME); + $sel->title_is("Change Votes"); + $sel->type_ok("bug_$bug1_id", 1); + $sel->click_ok("change"); + $sel->wait_for_page_to_load_ok(WAIT_TIME); + $sel->title_is("Change Votes"); + $sel->is_text_present_ok("The changes to your votes have been saved"); + + edit_product($sel, "Kill me nicely"); + $sel->type_ok("votestoconfirm", 1); + $sel->click_ok("update-product"); + $sel->wait_for_page_to_load_ok(WAIT_TIME); + $sel->title_is("Updating Product 'Kill me nicely'"); + $sel->is_text_present_ok("Updated number of votes needed to confirm a bug"); + $text = trim($sel->get_text("bugzilla-body")); + ok($text =~ /Bug $bug1_id confirmed by number of votes/, "Bug $bug1_id is confirmed by popular votes"); +} + +# Edit the bug. + +go_to_bug($sel, $bug1_id); +$sel->selected_label_is("product", "Kill me nicely"); +$sel->selected_label_is("bug_status", "CONFIRMED") if $config->{test_extensions}; +$sel->select_ok("target_milestone", "label=pre-0.1"); +$sel->select_ok("component", "label=second comp"); +edit_bug_and_return($sel, $bug1_id, $bug_summary); +@cc_list = $sel->get_select_options("cc"); +ok(grep($_ eq $permanent_user, @cc_list), "User $permanent_user automatically added to the CC list"); + +# Delete the milestone the bug belongs to. This should retarget the bug +# to the default milestone. + +edit_product($sel, "Kill me nicely"); +$sel->click_ok("link=Edit milestones:"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Select milestone of product 'Kill me nicely'"); +$sel->click_ok('//a[@href="editmilestones.cgi?action=del&product=Kill%20me%20nicely&milestone=pre-0.1"]'); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Delete Milestone of Product 'Kill me nicely'"); +$text = trim($sel->get_text("bugzilla-body")); +ok($text =~ /There is 1 bug entered for this milestone/, "Warning displayed"); +ok($text =~ /Do you really want to delete this milestone\?/, "Requesting confirmation"); +$sel->click_ok("delete"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Milestone Deleted"); +$text = trim($sel->get_text("message")); +ok($text =~ /Bugs targetted to this milestone have been retargetted to the default milestone/, "Bug retargetted"); + +# Try deleting the version used by the bug. This action must be rejected. + +$sel->click_ok("link='Kill me nicely'"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Edit Product 'Kill me nicely'"); +$sel->click_ok("link=Edit versions:"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Select version of product 'Kill me nicely'"); +$sel->click_ok("//a[contains(\@href, 'editversions.cgi?action=del&product=Kill%20me%20nicely&version=0.1a')]"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Delete Version of Product 'Kill me nicely'"); +$text = trim($sel->get_text("bugzilla-body")); +ok($text =~ /Sorry, there are 2 outstanding bugs for this version/, "Rejecting version deletion"); +$sel->go_back_ok(); +$sel->wait_for_page_to_load_ok(WAIT_TIME); + +# Delete an unused version. The action must succeed. + +$sel->click_ok('//a[@href="editversions.cgi?action=del&product=Kill%20me%20nicely&version=0.1"]'); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Delete Version of Product 'Kill me nicely'"); +$text = trim($sel->get_text("bugzilla-body")); +ok($text =~ /Do you really want to delete this version\?/, "Requesting confirmation"); +$sel->click_ok("delete"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Version Deleted"); + +# Delete the component the bug belongs to. The action must succeed. + +$sel->click_ok("link='Kill me nicely'"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Edit Product 'Kill me nicely'"); +$sel->click_ok("link=Edit components:"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Select component of product 'Kill me nicely'"); +$sel->click_ok("//a[contains(\@href, 'editcomponents.cgi?action=del&product=Kill%20me%20nicely&component=second%20comp')]"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Delete component 'second comp' from 'Kill me nicely' product"); +$text = trim($sel->get_text("bugzilla-body")); +ok($text =~ /There are 2 bugs entered for this component/, "Warning displayed"); +ok($text =~ /Do you really want to delete this component\?/, "Requesting confirmation"); +$sel->click_ok("delete"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Component Deleted"); +$text = trim($sel->get_text("bugzilla-body")); +ok($text =~ /The component second comp has been deleted/, "Component deletion confirmed"); +ok($text =~ /All bugs being in this component and all references to them have also been deleted/, + "Bug deletion confirmed"); + +# Only one value for component, version and milestone available. They should +# be selected by default. + +file_bug_in_product($sel, "Kill me nicely"); +$bug_summary2 = "bye bye everybody!"; +$sel->type_ok("short_desc", $bug_summary2); +$sel->type_ok("comment", "I'm dead :("); +create_bug($sel, $bug_summary2); + +# Now delete the product. + +go_to_admin($sel); +$sel->click_ok("link=Products"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Select product"); +$sel->click_ok("//a[\@href='editproducts.cgi?action=del&product=Kill%20me%20nicely']"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Delete Product 'Kill me nicely'"); +$text = trim($sel->get_text("bugzilla-body")); +ok($text =~ /There is 1 bug entered for this product/, "Warning displayed"); +ok($text =~ /Do you really want to delete this product\?/, "Confirmation request displayed"); +$sel->click_ok("delete"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Product Deleted"); +logout($sel); diff --git a/xt/selenium/email_preferences.t b/xt/selenium/email_preferences.t new file mode 100644 index 000000000..c1e60b05a --- /dev/null +++ b/xt/selenium/email_preferences.t @@ -0,0 +1,405 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# This Source Code Form is "Incompatible With Secondary Licenses", as +# defined by the Mozilla Public License, v. 2.0. + +use 5.10.1; +use strict; +use warnings; + +use FindBin qw($RealBin); +use lib "$RealBin/../lib"; + +use Test::More "no_plan"; + +use QA::Util; + +my ($sel, $config) = get_selenium(); + +# Used to test sent bugmails +use constant RCPT_BOTH => 1; +use constant RCPT_ADMIN => 2; +use constant RCPT_NORMAL => 3; +use constant RCPT_NONE => 4; +my @email_both = ($config->{admin_user_login}, $config->{editbugs_user_login}); +my @email_admin = ($config->{admin_user_login}); +my @email_normal = ($config->{editbugs_user_login}); +my @email_none = ("no one"); + +# Test script to test email preferences. +# For reference, following bugmail and request mails should be generated. +# +# Admin should get following bugmails (in order): +# 1) A bug is created +# 2) Normal user adds a CC for itself +# 3) Admin removes CC of normal user +# 4) Admin assigns the bug to itself +# 5) Admin requests a flag from normal user +# 6) Admin grants a flag requested from itself +# 7) Normal user set severity to normal +# 8) Normal user adds a comment #3 +# 9) Normal user assigns the bug to itself +# Normal User should get following bugmail (in order): +# 1) A bug is created +# 2) Normal user sets severity to blocker +# 3) Admin sets severity to trivial +# 4) Admin adds a comment #2 +# 5) Admin removes CC of normal user +# 6) Admin assigns the bug to itself +# 7) Normal user sets severity to normal +# +# Admin should get following request mails (in order): +# 1) Normal user denies a flag requested by the admin +# Normal user should get following request mails (in order): +# 1) Admin requests a flag from normal user +# +# NOTE that only correct bugmail is verified by the test script because +# sending request mail is not indicated on the UI. + +# Set admin Email Prefs (via link in footer) +log_in($sel, $config, 'admin'); +$sel->click_ok("link=Preferences"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("General Preferences"); +$sel->click_ok("link=Email Notifications"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->is_text_present_ok("Email Notifications"); +$sel->click_ok("//input[\@value='Disable All Mail']"); +$sel->click_ok("email-0-1", undef, 'Set "I\'m added to or removed from this capacity" for Assignee role'); +$sel->click_ok("email-0-5", undef, 'Set "The priority, status, severity, or milestone changes" for Assignee role'); +$sel->click_ok("email-0-2", undef, 'Set "New comments are added" for Assignee role'); +$sel->click_ok("email-0-0", undef, 'Set "Any field not mentioned above changes" for Assignee role'); +$sel->click_ok("email-3-8", undef, 'Set "The CC field changes" for CCed role'); +$sel->click_ok("email-1-10", undef, 'Set "A new bug is created" for QA Contact role'); +$sel->click_ok("email-100-101", undef, 'Set "Email me when someone sets a flag I asked for" global option'); +# Restore the old 4.2 behavior for 'Disable All Mail'. +foreach my $col (0..3) { + foreach my $row (50..51) { + $sel->click_ok("neg-email-$col-$row"); + } +} +$sel->value_is("email-0-1", "on"); +$sel->value_is("email-0-10", "off"); +$sel->value_is("email-0-6", "off"); +$sel->value_is("email-0-5", "on"); +$sel->value_is("email-0-2", "on"); +$sel->value_is("email-0-3", "off"); +$sel->value_is("email-0-4", "off"); +$sel->value_is("email-0-7", "off"); +$sel->value_is("email-0-8", "off"); +$sel->value_is("email-0-9", "off"); +$sel->value_is("email-0-0", "on"); +$sel->value_is("neg-email-0-50", "off"); +$sel->value_is("neg-email-0-51", "off"); +$sel->value_is("email-1-1", "off"); +$sel->value_is("email-1-10", "on"); +$sel->value_is("email-1-6", "off"); +$sel->value_is("email-1-5", "off"); +$sel->value_is("email-1-2", "off"); +$sel->value_is("email-1-3", "off"); +$sel->value_is("email-1-4", "off"); +$sel->value_is("email-1-7", "off"); +$sel->value_is("email-1-8", "off"); +$sel->value_is("email-1-9", "off"); +$sel->value_is("email-1-0", "off"); +$sel->value_is("neg-email-1-50", "off"); +$sel->value_is("neg-email-1-51", "off"); +ok(!$sel->is_editable("email-2-1"), 'The "I\'m added to or removed from this capacity" for Reporter role is disabled'); +$sel->value_is("email-2-10", "off"); +$sel->value_is("email-2-6", "off"); +$sel->value_is("email-2-5", "off"); +$sel->value_is("email-2-2", "off"); +$sel->value_is("email-2-3", "off"); +$sel->value_is("email-2-4", "off"); +$sel->value_is("email-2-7", "off"); +$sel->value_is("email-2-8", "off"); +$sel->value_is("email-2-9", "off"); +$sel->value_is("email-2-0", "off"); +$sel->value_is("neg-email-2-50", "off"); +$sel->value_is("neg-email-2-51", "off"); +$sel->value_is("email-3-1", "off"); +$sel->value_is("email-3-10", "off"); +$sel->value_is("email-3-6", "off"); +$sel->value_is("email-3-5", "off"); +$sel->value_is("email-3-2", "off"); +$sel->value_is("email-3-3", "off"); +$sel->value_is("email-3-4", "off"); +$sel->value_is("email-3-7", "off"); +$sel->value_is("email-3-8", "on"); +$sel->value_is("email-3-9", "off"); +$sel->value_is("email-3-0", "off"); +$sel->value_is("neg-email-3-50", "off"); +$sel->value_is("neg-email-3-51", "off"); +$sel->value_is("email-100-100", "off"); +$sel->value_is("email-100-101", "on"); +$sel->click_ok("update", undef, "Submit modified admin email preferences"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->is_text_present_ok("The changes to your email notifications have been saved."); + +# Set "After changing a bug" default preference to "Show the updated bug" +# This simplifies bug changes below +go_to_admin($sel); +$sel->click_ok("link=Default Preferences"); +$sel->wait_for_page_to_load(WAIT_TIME); +$sel->title_is("Default Preferences"); +$sel->select_ok("post_bug_submit_action", "label=Show the updated bug"); +$sel->click_ok("update"); +$sel->wait_for_page_to_load(WAIT_TIME); +$sel->title_is("Default Preferences"); + +# Set normal user Email Prefs +logout($sel); +log_in($sel, $config, 'editbugs'); +$sel->click_ok("link=Preferences"); +$sel->wait_for_page_to_load(WAIT_TIME); +$sel->title_is("General Preferences"); +$sel->click_ok("link=Email Notifications"); +$sel->wait_for_page_to_load(WAIT_TIME); +$sel->title_is("Email Notifications"); +$sel->is_text_present_ok("Email Notifications"); +$sel->click_ok("//input[\@value='Enable All Mail']"); +$sel->click_ok("email-3-1", undef, 'Clear "I\'m added to or removed from this capacity" for CCed role'); +$sel->click_ok("email-3-5", undef, 'Clear "The priority, status, severity, or milestone changes" for CCed role'); +$sel->click_ok("email-2-2", undef, 'Clear "New comments are added" for Reporter role'); +$sel->click_ok("email-3-2", undef, 'Clear "New comments are added" for CCed role'); +$sel->click_ok("email-2-8", undef, 'Clear "The CC field changes" for Reporter role'); +$sel->click_ok("email-3-8", undef, 'Clear "The CC field changes" for CCed role'); +$sel->click_ok("email-2-0", undef, 'Clear "Any field not mentioned above changes" for Reporter role'); +$sel->click_ok("email-3-0", undef, 'Clear "Any field not mentioned above changes" for CCed role'); +$sel->click_ok("neg-email-0-51", undef, 'Set "Change was made by me" override for Assignee role'); +$sel->click_ok("email-100-101", undef, 'Clear "Email me when someone sets a flag I asked for" global option'); +$sel->value_is("email-0-1", "on"); +$sel->value_is("email-0-10", "on"); +$sel->value_is("email-0-6", "on"); +$sel->value_is("email-0-5", "on"); +$sel->value_is("email-0-2", "on"); +$sel->value_is("email-0-3", "on"); +$sel->value_is("email-0-4", "on"); +$sel->value_is("email-0-7", "on"); +$sel->value_is("email-0-8", "on"); +$sel->value_is("email-0-9", "on"); +$sel->value_is("email-0-0", "on"); +$sel->value_is("neg-email-0-50", "off"); +$sel->value_is("neg-email-0-51", "on"); +$sel->value_is("email-1-1", "on"); +$sel->value_is("email-1-10", "on"); +$sel->value_is("email-1-6", "on"); +$sel->value_is("email-1-5", "on"); +$sel->value_is("email-1-2", "on"); +$sel->value_is("email-1-3", "on"); +$sel->value_is("email-1-4", "on"); +$sel->value_is("email-1-7", "on"); +$sel->value_is("email-1-8", "on"); +$sel->value_is("email-1-9", "on"); +$sel->value_is("email-1-0", "on"); +$sel->value_is("neg-email-1-50", "off"); +$sel->value_is("neg-email-1-51", "off"); +ok(!$sel->is_editable("email-2-1"), 'The "I\'m added to or removed from this capacity" for Reporter role is disabled'); +$sel->value_is("email-2-10", "on"); +$sel->value_is("email-2-6", "on"); +$sel->value_is("email-2-5", "on"); +$sel->value_is("email-2-2", "off"); +$sel->value_is("email-2-3", "on"); +$sel->value_is("email-2-4", "on"); +$sel->value_is("email-2-7", "on"); +$sel->value_is("email-2-8", "off"); +$sel->value_is("email-2-9", "on"); +$sel->value_is("email-2-0", "off"); +$sel->value_is("neg-email-2-50", "off"); +$sel->value_is("neg-email-2-51", "off"); +$sel->value_is("email-3-1", "off"); +$sel->value_is("email-3-10", "on"); +$sel->value_is("email-3-6", "on"); +$sel->value_is("email-3-5", "off"); +$sel->value_is("email-3-2", "off"); +$sel->value_is("email-3-3", "on"); +$sel->value_is("email-3-4", "on"); +$sel->value_is("email-3-7", "on"); +$sel->value_is("email-3-8", "off"); +$sel->value_is("email-3-9", "on"); +$sel->value_is("email-3-0", "off"); +$sel->value_is("neg-email-3-50", "off"); +$sel->value_is("neg-email-3-51", "off"); +$sel->value_is("email-100-100", "on"); +$sel->value_is("email-100-101", "off"); +$sel->click_ok("update", undef, "Submit modified normal user email preferences"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->is_text_present_ok("The changes to your email notifications have been saved."); + +# Create a test bug (bugmail to both normal user and admin) +file_bug_in_product($sel, "Another Product"); +$sel->select_ok("component", "label=c1"); +my $bug_summary = "Selenium Email Preference test bug"; +$sel->type_ok("short_desc", $bug_summary, "Enter bug summary"); +$sel->type_ok("comment", "Created by Selenium to test Email Notifications", "Enter bug description"); +$sel->type_ok("assigned_to", $config->{editbugs_user_login}); +$sel->type_ok("qa_contact", $config->{admin_user_login}); +$sel->type_ok("cc", $config->{admin_user_login}); +my $bug1_id = create_bug($sel, $bug_summary); +verify_bugmail_recipients($sel, RCPT_BOTH); + +# Make normal user changes (first pass) +# +go_to_bug($sel, $bug1_id); +# Severity change (bugmail to normal user but not admin) +$sel->select_ok("bug_severity", "label=blocker"); +$sel->selected_label_is("bug_severity", "blocker"); +edit_bug($sel, $bug1_id, $bug_summary); +verify_bugmail_recipients($sel, RCPT_NORMAL); +# Add a comment (bugmail to no one) +$sel->type_ok("comment", "This is a Selenium generated normal user test comment 1 of 2. (No bugmail should be generated for this.)"); +$sel->value_is("comment", "This is a Selenium generated normal user test comment 1 of 2. (No bugmail should be generated for this.)"); +edit_bug($sel, $bug1_id, $bug_summary); +verify_bugmail_recipients($sel, RCPT_NONE); +# Add normal user to CC list (bugmail to admin but not normal user) +$sel->type_ok("newcc", $config->{editbugs_user_login}); +$sel->value_is("newcc", $config->{editbugs_user_login}); +edit_bug($sel, $bug1_id, $bug_summary); +verify_bugmail_recipients($sel, RCPT_ADMIN); +# Request a flag from admin (bugmail to no one, request mail to no one) +$sel->select_ok("flag_type-1", "label=?"); +$sel->type_ok("requestee_type-1", $config->{admin_user_login}); +$sel->value_is("requestee_type-1", $config->{admin_user_login}); +edit_bug($sel, $bug1_id, $bug_summary); +verify_bugmail_recipients($sel, RCPT_NONE); + +# Make admin changes +# +logout($sel); +log_in($sel, $config, 'admin'); +go_to_bug($sel, $bug1_id); +# Severity change (bugmail to normal user but not admin) +$sel->select_ok("bug_severity", "label=trivial"); +$sel->selected_label_is("bug_severity", "trivial"); +edit_bug($sel, $bug1_id, $bug_summary); +verify_bugmail_recipients($sel, RCPT_NORMAL); +# Add a comment (bugmail to normal user but not admin) +$sel->type_ok("comment", "This is a Selenium generated admin user test comment. (Only normal user should get bugmail for this.)"); +$sel->value_is("comment", "This is a Selenium generated admin user test comment. (Only normal user should get bugmail for this.)"); +edit_bug($sel, $bug1_id, $bug_summary); +verify_bugmail_recipients($sel, RCPT_NORMAL); +# Remove normal user from CC list (bugmail to both normal user and admin) +$sel->click_ok("removecc"); +$sel->add_selection_ok("cc", "label=$config->{editbugs_user_login}"); +$sel->value_is("removecc", "on"); +$sel->selected_label_is("cc", $config->{editbugs_user_login}); +edit_bug($sel, $bug1_id, $bug_summary); +verify_bugmail_recipients($sel, RCPT_BOTH); +# Reassign bug to admin user (bugmail to both normal user and admin) +$sel->type_ok("assigned_to", $config->{admin_user_login}); +$sel->value_is("assigned_to", $config->{admin_user_login}); +edit_bug($sel, $bug1_id, $bug_summary); +verify_bugmail_recipients($sel, RCPT_BOTH); +# Request a flag from normal user (bugmail to admin but not normal user and request mail to admin) +$sel->select_ok("flag_type-1", "label=?"); +$sel->type_ok("requestee_type-1", $config->{editbugs_user_login}); +$sel->value_is("requestee_type-1", $config->{editbugs_user_login}); +edit_bug($sel, $bug1_id, $bug_summary); +verify_bugmail_recipients($sel, RCPT_ADMIN); +# Grant a normal user flag request (bugmail to admin but not normal user and request mail to no one) +my $flag1_id = set_flag($sel, $config->{admin_user_login}, "?", "+"); +edit_bug($sel, $bug1_id, $bug_summary); +verify_bugmail_recipients($sel, RCPT_ADMIN); + +# Make normal user changes (second pass) +# +logout($sel); +log_in($sel, $config, 'editbugs'); +go_to_bug($sel, $bug1_id); +# Severity change (bugmail to both admin and normal user) +$sel->select_ok("bug_severity", "label=normal"); +$sel->selected_label_is("bug_severity", "normal"); +edit_bug($sel, $bug1_id, $bug_summary); +verify_bugmail_recipients($sel, RCPT_BOTH); +# Add a comment (bugmail to admin but not normal user) +$sel->type_ok("comment", "This is a Selenium generated normal user test comment 2 of 2. (Only admin should get bugmail for this.)"); +$sel->value_is("comment", "This is a Selenium generated normal user test comment 2 of 2. (Only admin should get bugmail for this.)"); +edit_bug($sel, $bug1_id, $bug_summary); +verify_bugmail_recipients($sel, RCPT_ADMIN); +# Reassign to normal user (bugmail to admin but not normal user) +$sel->type_ok("assigned_to", $config->{editbugs_user_login}); +$sel->value_is("assigned_to", $config->{editbugs_user_login}); +edit_bug($sel, $bug1_id, $bug_summary); +verify_bugmail_recipients($sel, RCPT_ADMIN); +# Deny a flag requested by admin (bugmail to no one and request mail to admin) +my $flag2_id = set_flag($sel, $config->{editbugs_user_login}, "?", "-"); +edit_bug($sel, $bug1_id, $bug_summary); +verify_bugmail_recipients($sel, RCPT_NONE); +# Cancel both flags (bugmail and request mail to no one) +set_flag($sel, undef, "+", "X", $flag1_id); +set_flag($sel, undef, "-", "X", $flag2_id); +edit_bug($sel, $bug1_id, $bug_summary); +verify_bugmail_recipients($sel, RCPT_NONE); +logout($sel); + +# Set "After changing a bug" default preference back to "Do Nothing". +log_in($sel, $config, 'admin'); +go_to_admin($sel); +$sel->click_ok("link=Default Preferences"); +$sel->wait_for_page_to_load(WAIT_TIME); +$sel->title_is("Default Preferences"); +$sel->select_ok("post_bug_submit_action", "label=Do Nothing"); +$sel->click_ok("update"); +$sel->wait_for_page_to_load(WAIT_TIME); +$sel->title_is("Default Preferences"); +logout($sel); + +# Help functions +sub verify_bugmail_recipients { + my ($sel, $rcpt_sentto) = @_; + my $wanted_sentto; + my $err = 0; + + # Verify sentto field + my @email_sentto + = sort split(/, /, $sel->get_text("//dt[text()='Email sent to:']/following-sibling::dd")); + if ($rcpt_sentto == RCPT_BOTH) { + $wanted_sentto = \@email_both; + is_deeply(\@email_sentto, $wanted_sentto, "Bugmail sent to both") + or $err = 1; + } + elsif ($rcpt_sentto == RCPT_ADMIN) { + $wanted_sentto = \@email_admin; + is_deeply(\@email_sentto, $wanted_sentto, "Bugmail sent to admin") + or $err = 1; + } + elsif ($rcpt_sentto == RCPT_NORMAL) { + $wanted_sentto = \@email_normal; + is_deeply(\@email_sentto, $wanted_sentto, "Bugmail sent to normal user") + or $err = 1; + } else { + $wanted_sentto = \@email_none; + is_deeply(\@email_sentto, $wanted_sentto, "Bugmail sent to no one") + or $err = 1; + } + + # In case of an error, retrieve and show diagnostics info + if ($err) { + diag("Sent, actual : " . join(', ', @email_sentto)); + diag("Sent, wanted : " . join(', ', @$wanted_sentto)); + diag("Changer : " . trim($sel->get_text('//a[contains(@href, "logout")]/../text()[3]'))); + diag("Reporter : " . $sel->get_attribute('//th[contains(text(), "Reported:")]/following-sibling::td//a@title')); + diag("Assignee : " . $sel->get_value('assigned_to')); + diag("QA contact : " . $sel->get_value('qa_contact')); + diag("CC List : " . join(', ', $sel->get_select_options('cc'))); + } +} + +sub set_flag { + my ($sel, $login, $curval, $newval, $prev_id) = @_; + + # Retrieve flag id for the flag to be set + my $flag_id = $prev_id; + if (defined $login) { + my $flag_name = $sel->get_attribute("//table[\@id='flags']//input[\@value='$login']\@name"); + $flag_name =~ /^requestee-(\d+)$/; + $flag_id = $1; + } + + # Set new value for the flag (verifies current value) + $sel->select_ok("//select[\@id=\"flag-$flag_id\"]/option[\@value=\"$curval\" and \@selected]/..", "value=$newval", "Set flag ID $flag_id to $newval from $curval"); + + return $flag_id; +} diff --git a/xt/selenium/enter_new_bug.t b/xt/selenium/enter_new_bug.t new file mode 100644 index 000000000..404d30f10 --- /dev/null +++ b/xt/selenium/enter_new_bug.t @@ -0,0 +1,35 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# This Source Code Form is "Incompatible With Secondary Licenses", as +# defined by the Mozilla Public License, v. 2.0. + +use 5.10.1; +use strict; +use warnings; + +use FindBin qw($RealBin); +use lib "$RealBin/../lib"; + +use Test::More "no_plan"; + +use QA::Util; + +my ($sel, $config) = get_selenium(); + +# Very simple test script to test if bug creation with minimal data +# passes successfully for different user privileges. +# +# More elaborate tests exist in other scripts. This doesn't mean this +# one could not be improved a bit. + +my $bug_summary = "Bug created by Selenium"; +foreach my $user (qw(admin unprivileged canconfirm)) { + log_in($sel, $config, $user); + file_bug_in_product($sel, "TestProduct"); + $sel->type_ok("short_desc", $bug_summary, "Enter bug summary"); + $sel->type_ok("comment", "--- Bug created by Selenium ---", "Enter bug description"); + create_bug($sel, $bug_summary); + logout($sel); +} diff --git a/xt/selenium/flags.t b/xt/selenium/flags.t new file mode 100644 index 000000000..dd4a0ffa8 --- /dev/null +++ b/xt/selenium/flags.t @@ -0,0 +1,441 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# This Source Code Form is "Incompatible With Secondary Licenses", as +# defined by the Mozilla Public License, v. 2.0. + +use 5.10.1; +use strict; +use warnings; + +use FindBin qw($RealBin); +use lib "$RealBin/../lib"; + +use Test::More "no_plan"; + +use QA::Util; + +# We have to upload files from the local computer. This requires +# chrome privileges. +my ($sel, $config) = get_selenium(CHROME_MODE); + +# First create a flag type for bugs. + +log_in($sel, $config, 'admin'); +go_to_admin($sel); +$sel->click_ok("link=Flags"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Administer Flag Types"); +$sel->click_ok("link=Create Flag Type for Bugs"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Create Flag Type for Bugs"); +$sel->type_ok("name", "SeleniumBugFlag1Test"); +$sel->type_ok("description", "bugflag1"); +$sel->select_ok("product", "label=TestProduct"); +$sel->click_ok("categoryAction-include"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Create Flag Type for Bugs"); +$sel->remove_all_selections_ok("inclusion_to_remove"); +$sel->add_selection_ok("inclusion_to_remove", "label=__Any__:__Any__"); +$sel->click_ok("categoryAction-removeInclusion"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Create Flag Type for Bugs"); +$sel->select_ok("product", "label=QA-Selenium-TEST"); +$sel->click_ok("categoryAction-exclude"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Create Flag Type for Bugs"); +$sel->select_ok("product", "label=QA-Selenium-TEST"); +$sel->click_ok("categoryAction-include"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Create Flag Type for Bugs"); +my @inclusion = $sel->get_select_options("inclusion_to_remove"); +ok(scalar @inclusion == 2, "The inclusion list contains 2 elements"); +ok(grep($_ eq "QA-Selenium-TEST:__Any__", @inclusion), "QA-Selenium-TEST:__Any__ is in the inclusion list"); +ok(grep($_ eq "TestProduct:__Any__", @inclusion), "TestProduct:__Any__ is in the inclusion list"); +my @exclusion = $sel->get_select_options("exclusion_to_remove"); +ok(scalar @exclusion == 1, "The exclusion list contains 1 element"); +ok($exclusion[0] eq "QA-Selenium-TEST:__Any__", "QA-Selenium-TEST:__Any__ is in the exclusion list"); +$sel->type_ok("sortkey", "900"); +$sel->value_is("cc_list", ""); +$sel->value_is("is_active", "on"); +$sel->value_is("is_requestable", "on"); +$sel->value_is("is_requesteeble", "on"); +$sel->value_is("is_multiplicable", "on"); +$sel->select_ok("grant_group", "label=admin"); +$sel->select_ok("request_group", "label=(no group)"); +$sel->click_ok("save"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Flag Type 'SeleniumBugFlag1Test' Created"); +$sel->is_text_present_ok("The flag type SeleniumBugFlag1Test has been created."); +my $flagtype_url = $sel->get_attribute('link=SeleniumBugFlag1Test@href'); +$flagtype_url =~ /id=(\d+)$/; +my $flagtype1_id = $1; + +# Clone the flag type, but set the request group to 'editbugs' and the sortkey to 950. + +$sel->click_ok("//a[\@href='editflagtypes.cgi?action=copy&id=$flagtype1_id']"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Create Flag Type for Bugs Based on SeleniumBugFlag1Test"); +$sel->type_ok("name", "SeleniumBugFlag2Test"); +$sel->type_ok("description", "bugflag2"); +@inclusion = $sel->get_select_options("inclusion_to_remove"); +ok(scalar @inclusion == 2, "The inclusion list contains 2 elements"); +ok(grep($_ eq "QA-Selenium-TEST:__Any__", @inclusion), "QA-Selenium-TEST:__Any__ is in the inclusion list"); +ok(grep($_ eq "TestProduct:__Any__", @inclusion), "TestProduct:__Any__ is in the inclusion list"); +@exclusion = $sel->get_select_options("exclusion_to_remove"); +ok(scalar @exclusion == 1, "The exclusion list contains 1 element"); +ok($exclusion[0] eq "QA-Selenium-TEST:__Any__", "QA-Selenium-TEST:__Any__ is in the exclusion list"); +$sel->type_ok("sortkey", "950"); +$sel->value_is("is_active", "on"); +$sel->value_is("is_requestable", "on"); +$sel->value_is("is_requesteeble", "on"); +$sel->value_is("is_multiplicable", "on"); +$sel->type_ok("cc_list", $config->{canconfirm_user_login}); +$sel->selected_label_is("grant_group", "admin"); +$sel->select_ok("request_group", "label=editbugs"); +$sel->click_ok("save"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Flag Type 'SeleniumBugFlag2Test' Created"); +$sel->is_text_present_ok("The flag type SeleniumBugFlag2Test has been created."); +$flagtype_url = $sel->get_attribute('link=SeleniumBugFlag2Test@href'); +$flagtype_url =~ /id=(\d+)$/; +my $flagtype2_id = $1; + +# Clone the first flag type again, but with different attributes. + +$sel->click_ok("//a[\@href='editflagtypes.cgi?action=copy&id=$flagtype1_id']"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Create Flag Type for Bugs Based on SeleniumBugFlag1Test"); +$sel->type_ok("name", "SeleniumBugFlag3Test"); +$sel->type_ok("description", "bugflag3"); +$sel->type_ok("sortkey", "980"); +$sel->value_is("is_active", "on"); +$sel->value_is("is_requestable", "on"); +$sel->uncheck_ok("is_requesteeble"); +$sel->uncheck_ok("is_multiplicable"); +$sel->value_is("cc_list", ""); +$sel->select_ok("grant_group", "label=(no group)"); +$sel->selected_label_is("request_group", "(no group)"); +$sel->click_ok("save"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Flag Type 'SeleniumBugFlag3Test' Created"); +$sel->is_text_present_ok("The flag type SeleniumBugFlag3Test has been created."); +$flagtype_url = $sel->get_attribute('link=SeleniumBugFlag3Test@href'); +$flagtype_url =~ /id=(\d+)$/; +my $flagtype3_id = $1; + +# We now create a flag type for attachments. + +$sel->click_ok("link=Create Flag Type For Attachments"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Create Flag Type for Attachments"); +$sel->type_ok("name", "SeleniumAttachmentFlag1Test"); +$sel->type_ok("description", "attachmentflag1"); +$sel->select_ok("product", "label=TestProduct"); +$sel->click_ok("categoryAction-include"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Create Flag Type for Attachments"); +$sel->remove_all_selections_ok("inclusion_to_remove"); +$sel->add_selection_ok("inclusion_to_remove", "label=__Any__:__Any__"); +$sel->click_ok("categoryAction-removeInclusion"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Create Flag Type for Attachments"); +@inclusion = $sel->get_select_options("inclusion_to_remove"); +ok(scalar @inclusion == 1, "The inclusion list contains 1 element"); +ok($inclusion[0] eq "TestProduct:__Any__", "TestProduct:__Any__ is in the exclusion list"); +$sel->type_ok("sortkey", "700"); +$sel->value_is("cc_list", ""); +$sel->select_ok("grant_group", "label=editbugs"); +$sel->select_ok("request_group", "label=canconfirm"); +$sel->click_ok("save"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Flag Type 'SeleniumAttachmentFlag1Test' Created"); +$sel->is_text_present_ok("The flag type SeleniumAttachmentFlag1Test has been created."); +$flagtype_url = $sel->get_attribute('link=SeleniumAttachmentFlag1Test@href'); +$flagtype_url =~ /id=(\d+)$/; +my $aflagtype1_id = $1; + +# Clone the flag type. + +$sel->click_ok("//a[\@href='editflagtypes.cgi?action=copy&id=$aflagtype1_id']"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Create Flag Type for Attachments Based on SeleniumAttachmentFlag1Test"); +$sel->type_ok("name", "SeleniumAttachmentFlag2Test"); +$sel->type_ok("description", "attachmentflag2"); +@inclusion = $sel->get_select_options("inclusion_to_remove"); +ok(scalar @inclusion == 1, "The inclusion list contains 1 element"); +ok($inclusion[0] eq "TestProduct:__Any__", "TestProduct:__Any__ is in the exclusion list"); +$sel->type_ok("sortkey", "750"); +$sel->type_ok("cc_list", $config->{admin_user_login}); +$sel->uncheck_ok("is_multiplicable"); +$sel->select_ok("grant_group", "label=(no group)"); +$sel->select_ok("request_group", "label=(no group)"); +$sel->click_ok("save"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Flag Type 'SeleniumAttachmentFlag2Test' Created"); +$sel->is_text_present_ok("The flag type SeleniumAttachmentFlag2Test has been created."); +$flagtype_url = $sel->get_attribute('link=SeleniumAttachmentFlag2Test@href'); +$flagtype_url =~ /id=(\d+)$/; +my $aflagtype2_id = $1; + +# Clone the flag type again, and set it as inactive. + +$sel->click_ok("//a[\@href='editflagtypes.cgi?action=copy&id=$aflagtype1_id']"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Create Flag Type for Attachments Based on SeleniumAttachmentFlag1Test"); +$sel->type_ok("name", "SeleniumAttachmentFlag3Test"); +$sel->type_ok("description", "attachmentflag3"); +$sel->type_ok("sortkey", "800"); +$sel->uncheck_ok("is_active"); +$sel->click_ok("save"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Flag Type 'SeleniumAttachmentFlag3Test' Created"); +$sel->is_text_present_ok("The flag type SeleniumAttachmentFlag3Test has been created."); +$flagtype_url = $sel->get_attribute('link=SeleniumAttachmentFlag3Test@href'); +$flagtype_url =~ /id=(\d+)$/; +my $aflagtype3_id = $1; + +# All flag types have been created. Now "real" tests can start. + +file_bug_in_product($sel, 'TestProduct'); +my $bug_summary = "test flags"; +$sel->type_ok("short_desc", $bug_summary); +$sel->type_ok("comment", "this bug is used by Selenium to test flags"); +# Restrict the bug to the Master group. That's important for subsequent tests! +$sel->check_ok('//input[@name="groups" and @value="Master"]'); +my $bug1_id = create_bug($sel, $bug_summary); + +# All 3 bug flag types must be available; we are in the TestProduct product. + +$sel->is_text_present_ok("SeleniumBugFlag1Test"); +# We specify //select or //input, just to be sure. This is not required, though. +$sel->is_element_present_ok("//select[\@id='flag_type-$flagtype1_id']"); +$sel->is_element_present_ok("//input[\@id='requestee_type-$flagtype1_id']"); +# If fields are of the correct type above, we assume this is still true below. +$sel->is_text_present_ok("SeleniumBugFlag2Test"); +$sel->is_element_present_ok("flag_type-$flagtype2_id"); +$sel->is_element_present_ok("requestee_type-$flagtype2_id"); +$sel->is_text_present_ok("SeleniumBugFlag3Test"); +$sel->is_element_present_ok("flag_type-$flagtype3_id"); +ok(!$sel->is_element_present("requestee_type-$flagtype3_id"), "SeleniumBugFlag3Test is not specifically requestable"); + +# This is intentional to generate "flagmail". Some flags have a CC list +# associated with them, some others don't. This is to catch crashes due to +# the MTA. + +$sel->select_ok("flag_type-$flagtype1_id", "label=?"); +$sel->select_ok("flag_type-$flagtype2_id", "label=?"); +$sel->select_ok("flag_type-$flagtype3_id", "label=?"); +$sel->type_ok("comment", "Setting all 3 flags to ?"); +edit_bug_and_return($sel, $bug1_id, $bug_summary); + +# We need to store the new flag IDs. + +$sel->is_text_present_ok("$config->{admin_user_username}: SeleniumBugFlag1Test"); +my $flag1_1_id = $sel->get_attribute('//select[@title="bugflag1"]@id'); +$flag1_1_id =~ s/flag-//; +$sel->is_text_present_ok("$config->{admin_user_username}: SeleniumBugFlag2Test"); +my $flag2_1_id = $sel->get_attribute('//select[@title="bugflag2"]@id'); +$flag2_1_id =~ s/flag-//; +$sel->is_text_present_ok("$config->{admin_user_username}: SeleniumBugFlag3Test"); +my $flag3_1_id = $sel->get_attribute('//select[@title="bugflag3"]@id'); +$flag3_1_id =~ s/flag-//; + +$sel->is_text_present_ok("addl. SeleniumBugFlag1Test"); +$sel->is_text_present_ok("addl. SeleniumBugFlag2Test"); +ok(!$sel->is_text_present("addl. SeleniumBugFlag3Test"), "SeleniumBugFlag3Test is not multiplicable"); +$sel->select_ok("flag_type-$flagtype1_id", "label=+"); +$sel->select_ok("flag_type-$flagtype2_id", "label=-"); +edit_bug_and_return($sel, $bug1_id, $bug_summary); + +# Now let's test requestees. SeleniumBugFlag2Test requires the requestee +# to be in the editbugs group. + +$sel->select_ok("flag_type-$flagtype1_id", "label=?"); +$sel->type_ok("requestee_type-$flagtype1_id", $config->{admin_user_login}); +$sel->select_ok("flag_type-$flagtype2_id", "label=?"); +$sel->type_ok("requestee_type-$flagtype2_id", $config->{unprivileged_user_login}); +$sel->click_ok("commit"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Flag Requestee Not Authorized"); +$sel->go_back_ok(); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_like(qr/^$bug1_id /); +$sel->type_ok("requestee_type-$flagtype2_id", $config->{admin_user_login}); +edit_bug_and_return($sel, $bug1_id, $bug_summary); + +# Final tests for bug flags. + +$sel->select_ok("flag-$flag1_1_id", "value=X"); +$sel->select_ok("flag-$flag2_1_id", "label=+"); +$sel->select_ok("flag-$flag3_1_id", "label=-"); +edit_bug_and_return($sel, $bug1_id, $bug_summary); + +# Now we test attachment flags. + +$sel->click_ok("link=Add an attachment"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Create New Attachment for Bug #$bug1_id"); +$sel->type_ok("data", $config->{attachment_file}); +$sel->type_ok("description", "patch, v1"); +$sel->check_ok("ispatch"); +$sel->is_text_present_ok("SeleniumAttachmentFlag1Test"); +$sel->is_text_present_ok("SeleniumAttachmentFlag2Test"); +ok(!$sel->is_text_present("SeleniumAttachmentFlag3Test"), "Inactive SeleniumAttachmentFlag3Test flag type not displayed"); + +# Let's generate some "flagmail", first with no requestee. + +$sel->select_ok("flag_type-$aflagtype1_id", "label=?"); +$sel->select_ok("flag_type-$aflagtype2_id", "label=?"); +$sel->type_ok("comment", "patch for testing purposes only"); +edit_bug($sel, $bug1_id, $bug_summary, {id => "create"}); + +# Store the flag ID. + +my $alink = $sel->get_attribute('//a[@title="patch, v1"]@href'); +$alink =~ /id=(\d+)/; +my $attachment1_id = $1; + +# Now create another attachment, and set requestees. + +$sel->click_ok("link=Create Another Attachment to Bug $bug1_id"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Create New Attachment for Bug #$bug1_id"); +$sel->type_ok("data", $config->{attachment_file}); +$sel->type_ok("description", "patch, v2"); +$sel->check_ok("ispatch"); +# Mark the previous attachment as obsolete. +$sel->check_ok($attachment1_id); +$sel->select_ok("flag_type-$aflagtype1_id", "label=?"); +$sel->type_ok("requestee_type-$aflagtype1_id", $config->{admin_user_login}); +$sel->select_ok("flag_type-$aflagtype2_id", "label=?"); +# The requestee is not in the Master group, and so he cannot view the bug. +# He must be silently skipped from the requestee field. +$sel->type_ok("requestee_type-$aflagtype2_id", $config->{unprivileged_user_login}); +$sel->type_ok("comment", "second patch, with requestee"); +edit_bug($sel, $bug1_id, $bug_summary, {id => "create"}); +$alink = $sel->get_attribute('//a[@title="patch, v2"]@href'); +$alink =~ /id=(\d+)/; +my $attachment2_id = $1; + +# Create a third attachment, but we now set the MIME type manually. + +$sel->click_ok("link=Create Another Attachment to Bug $bug1_id"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Create New Attachment for Bug #$bug1_id"); +$sel->type_ok("data", $config->{attachment_file}); +$sel->type_ok("description", "patch, v3"); +$sel->click_ok("list"); +$sel->select_ok("contenttypeselection", "label=plain text (text/plain)"); +$sel->select_ok("flag_type-$aflagtype1_id", "label=+"); +$sel->type_ok("comment", "one +, the other one blank"); +edit_bug($sel, $bug1_id, $bug_summary, {id => "create"}); +$alink = $sel->get_attribute('//a[@title="patch, v3"]@href'); +$alink =~ /id=(\d+)/; +my $attachment3_id = $1; + +# Display the bug and check flags are correctly set. + +$sel->click_ok("link=bug $bug1_id"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_like(qr/^$bug1_id /); +$sel->is_text_present_ok("$config->{admin_user_username}: SeleniumAttachmentFlag1Test? ($config->{admin_user_username})"); +$sel->is_text_present_ok("$config->{admin_user_username}: SeleniumAttachmentFlag2Test?"); +$sel->is_text_present_ok("$config->{admin_user_username}: SeleniumAttachmentFlag1Test+"); +# We marked the first attachment as obsolete, so it should have no flag on it. +$sel->is_text_present_ok("no flags"); + +# Make the bug public and log out. + +$sel->uncheck_ok('//input[@name="groups" and @value="Master"]'); +edit_bug($sel, $bug1_id, $bug_summary); +logout($sel); + +# As an unprivileged user, try to edit flags. + +log_in($sel, $config, 'unprivileged'); +go_to_bug($sel, $bug1_id); +# No privs are required to clear this flag. +$sel->select_ok("flag-$flag3_1_id", "value=X"); +edit_bug_and_return($sel, $bug1_id, $bug_summary); + +# editbugs privs are required to clear this flag, so no other option +# should be displayed besides the currently set "+". + +my @flag_states = $sel->get_select_options("flag-$flag2_1_id"); +ok(scalar(@flag_states) == 1 && $flag_states[0] eq '+', "Single flag state '+' available"); + +# Powerless users cannot set the flag to +, but setting it to ? is allowed. + +@flag_states = $sel->get_select_options("flag_type-$flagtype1_id"); +ok(scalar @flag_states == 2, "Two flag states available"); +ok(grep($_ eq '?', @flag_states), "Flag state '?' available"); + +# A powerless user cannot edit someone else's attachment flags. + +$sel->click_ok("//a[\@href='attachment.cgi?id=$attachment2_id&action=edit']"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_like(qr/Attachment $attachment2_id Details for Bug $bug1_id/); +ok($sel->is_element_present('//select[@title="attachmentflag2" and @disabled]'), + "Attachment flags are not editable by a powerless user"); + +# Add an attachment and set flags on it. + +$sel->click_ok("//a[contains(\@href, 'show_bug.cgi?id=$bug1_id')]"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_like(qr/^$bug1_id/); +$sel->click_ok("link=Add an attachment"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Create New Attachment for Bug #$bug1_id"); +$sel->type_ok("data", $config->{attachment_file}); +$sel->type_ok("description", "patch, v4"); +$sel->value_is("ispatch", "off"); +$sel->value_is("autodetect", "on"); + +# canconfirm/editbugs privs are required to edit this flag. + +ok(!$sel->is_element_present("flag_type-$aflagtype1_id"), "Flag type 'SeleniumAttachmentFlag1Test' not displayed to powerless users"); + +# No privs are required to edit this flag. + +$sel->select_ok("flag_type-$aflagtype2_id", "label=+"); +$sel->type_ok("comment", "granting again"); +edit_bug_and_return($sel, $bug1_id, $bug_summary, {id => "create"}); +$sel->is_text_present_ok("$config->{unprivileged_user_username}: SeleniumAttachmentFlag2Test+"); +logout($sel); + +# Final tests as an admin. He has editbugs privs, so he can edit +# someone else's patch. + +log_in($sel, $config, 'admin'); +go_to_bug($sel, $bug1_id); +$sel->click_ok("//a[\@href='attachment.cgi?id=${attachment3_id}&action=edit']"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_like(qr/Attachment $attachment3_id Details for Bug $bug1_id/); +$sel->select_ok('//select[@title="attachmentflag1"]', "label=+"); +edit_bug($sel, $bug1_id, $bug_summary, {id => "update"}); + +# It's time to delete all created flag types. + +go_to_admin($sel); +$sel->click_ok("link=Flags"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Administer Flag Types"); + +foreach my $flagtype ([$flagtype1_id, "SeleniumBugFlag1Test"], [$flagtype2_id, "SeleniumBugFlag2Test"], + [$flagtype3_id, "SeleniumBugFlag3Test"], [$aflagtype1_id, "SeleniumAttachmentFlag1Test"], + [$aflagtype2_id, "SeleniumAttachmentFlag2Test"], [$aflagtype3_id, "SeleniumAttachmentFlag3Test"]) +{ + my $flag_id = $flagtype->[0]; + my $flag_name = $flagtype->[1]; + $sel->click_ok("//a[\@href='editflagtypes.cgi?action=confirmdelete&id=$flag_id']"); + $sel->wait_for_page_to_load_ok(WAIT_TIME); + $sel->title_is("Confirm Deletion of Flag Type '$flag_name'"); + $sel->click_ok("link=Yes, delete"); + $sel->wait_for_page_to_load_ok(WAIT_TIME); + $sel->title_is("Flag Type '$flag_name' Deleted"); + my $msg = trim($sel->get_text("message")); + ok($msg eq "The flag type $flag_name has been deleted.", "Flag type $flag_name deleted"); +} +logout($sel); diff --git a/xt/selenium/flags2.t b/xt/selenium/flags2.t new file mode 100644 index 000000000..9b921612c --- /dev/null +++ b/xt/selenium/flags2.t @@ -0,0 +1,308 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# This Source Code Form is "Incompatible With Secondary Licenses", as +# defined by the Mozilla Public License, v. 2.0. + +use 5.10.1; +use strict; +use warnings; + +use FindBin qw($RealBin); +use lib "$RealBin/../lib"; + +use Test::More "no_plan"; + +use QA::Util; + +################################################################ +# 2nd script about flags. This one is focused on flag behavior # +# when moving a bug from one product/component to another one. # +################################################################ + +# We have to upload files from the local computer. This requires +# chrome privileges. +my ($sel, $config) = get_selenium(CHROME_MODE); + +# Start by creating a flag type for bugs. + +log_in($sel, $config, 'admin'); +go_to_admin($sel); +$sel->click_ok("link=Flags"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Administer Flag Types"); +$sel->click_ok("link=Create Flag Type for Bugs"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Create Flag Type for Bugs"); +$sel->type_ok("name", "selenium"); +$sel->type_ok("description", "Available in TestProduct and Another Product/c1"); +$sel->add_selection_ok("inclusion_to_remove", "label=__Any__:__Any__"); +$sel->click_ok("categoryAction-removeInclusion"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Create Flag Type for Bugs"); +$sel->select_ok("product", "label=TestProduct"); +$sel->selected_label_is("component", "__Any__"); +$sel->click_ok("categoryAction-include"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Create Flag Type for Bugs"); +$sel->select_ok("product", "label=Another Product"); +$sel->select_ok("component", "label=c1"); +$sel->click_ok("categoryAction-include"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Create Flag Type for Bugs"); + +# This flag type must have a higher sortkey than the one we will create later. +# The reason is that link=selenium will catch the first link with this name in +# the UI, so when the second flag type with this name is created, we have to +# catch it, not this one (which will be unique for now, so no worry to find it). + +$sel->type_ok("sortkey", 100); +$sel->value_is("is_active", "on"); +$sel->value_is("is_requestable", "on"); +$sel->click_ok("is_multiplicable"); +$sel->value_is("is_multiplicable", "off"); +$sel->select_ok("grant_group", "label=editbugs"); +$sel->select_ok("request_group", "label=canconfirm"); +$sel->click_ok("save"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Flag Type 'selenium' Created"); +$sel->is_text_present_ok("The flag type selenium has been created."); + +# Store the flag type ID. + +$sel->click_ok("link=selenium"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +my $flag_url = $sel->get_location(); +$flag_url =~ /id=(\d+)/; +my $flagtype1_id = $1; + +# Now create a flag type for attachments in 'Another Product'. + +$sel->go_back_ok(); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->click_ok("link=Create Flag Type For Attachments"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Create Flag Type for Attachments"); +$sel->type_ok("name", "selenium_review"); +$sel->type_ok("description", "Review flag used by Selenium"); +$sel->add_selection_ok("inclusion_to_remove", "label=__Any__:__Any__"); +$sel->click_ok("categoryAction-removeInclusion"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Create Flag Type for Attachments"); +$sel->select_ok("product", "label=Another Product"); +$sel->click_ok("categoryAction-include"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Create Flag Type for Attachments"); +$sel->type_ok("sortkey", 100); +$sel->value_is("is_active", "on"); +$sel->value_is("is_requestable", "on"); +$sel->click_ok("is_multiplicable"); +$sel->value_is("is_multiplicable", "off"); +$sel->selected_label_is("grant_group", "(no group)"); +$sel->selected_label_is("request_group", "(no group)"); +$sel->click_ok("save"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Flag Type 'selenium_review' Created"); +$sel->is_text_present_ok("The flag type selenium_review has been created."); + +# Store the flag type ID. + +$sel->click_ok("link=selenium_review"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$flag_url = $sel->get_location(); +$flag_url =~ /id=(\d+)/; +my $aflagtype1_id = $1; + +# Create a 2nd flag type for attachments, with the same name +# as the 1st one, but now *excluded* from 'Another Product'. + +$sel->go_back_ok(); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->click_ok("link=Create Flag Type For Attachments"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->type_ok("name", "selenium_review"); +$sel->type_ok("description", "Another review flag used by Selenium"); +$sel->select_ok("product", "label=Another Product"); +$sel->click_ok("categoryAction-include"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Create Flag Type for Attachments"); +$sel->type_ok("sortkey", 50); +$sel->value_is("is_active", "on"); +$sel->value_is("is_requestable", "on"); +$sel->value_is("is_multiplicable", "on"); +$sel->select_ok("grant_group", "label=editbugs"); +$sel->select_ok("request_group", "label=canconfirm"); +$sel->click_ok("save"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Flag Type 'selenium_review' Created"); + +# Store the flag type ID. + +$sel->click_ok("link=selenium_review"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$flag_url = $sel->get_location(); +$flag_url =~ /id=(\d+)/; +my $aflagtype2_id = $1; + +# We are done with the admin tasks. Now play with flags in bugs. + +file_bug_in_product($sel, 'TestProduct'); +$sel->select_ok("flag_type-$flagtype1_id", "label=+"); +my $bug_summary = "The selenium flag should be kept on product change"; +$sel->type_ok("short_desc", $bug_summary); +$sel->type_ok("comment", "pom"); +$sel->click_ok('//input[@value="Add an attachment"]'); +$sel->type_ok("data", $config->{attachment_file}); +$sel->type_ok("description", "small patch"); +$sel->click_ok("ispatch"); +$sel->value_is("ispatch", "on"); +ok(!$sel->is_element_present("flag_type-$aflagtype1_id"), "Flag type $aflagtype1_id not available in TestProduct"); +$sel->select_ok("flag_type-$aflagtype2_id", "label=-"); +my $bug1_id = create_bug($sel, $bug_summary); + +$sel->is_text_present_ok("$config->{admin_user_username}: selenium"); +my $flag1_id = $sel->get_attribute('//select[@title="Available in TestProduct and Another Product/c1"]@id'); +$flag1_id =~ s/flag-//; +$sel->selected_label_is("flag-$flag1_id", "+"); +$sel->is_text_present_ok("$config->{admin_user_username}: selenium_review-"); + +# Now move the bug into the 'Another Product' product. +# Both the bug and attachment flags should survive. + +$sel->select_ok("product", "label=Another Product"); +$sel->type_ok("comment", "Moving to Another Product / c1. The flag should be preserved."); +$sel->click_ok("commit"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Verify New Product Details..."); +$sel->select_ok("component", "label=c1"); +edit_bug_and_return($sel, $bug1_id, $bug_summary, {id => "change_product"}); +$sel->selected_label_is("flag-$flag1_id", "+"); +$sel->is_text_present_ok("$config->{admin_user_username}: selenium_review-"); + +# Now moving the bug into the c2 component. The bug flag +# won't survive, but the attachment flag should. + +$sel->type_ok("comment", "Moving to c2. The selenium flag will be deleted."); +$sel->select_ok("component", "label=c2"); +edit_bug_and_return($sel, $bug1_id, $bug_summary); +ok(!$sel->is_element_present("flag-$flag1_id"), "The selenium bug flag didn't survive"); +ok(!$sel->is_element_present("flag_type-$flagtype1_id"), "The selenium flag type doesn't exist"); +$sel->is_text_present_ok("$config->{admin_user_username}: selenium_review-"); + +# File a bug in 'Another Product / c2' and assign it +# to a powerless user, so that he can move it later. + +file_bug_in_product($sel, 'Another Product'); +$sel->select_ok("component", "label=c2"); +$sel->type_ok("assigned_to", $config->{unprivileged_user_login}); +ok(!$sel->is_editable("flag_type-$flagtype1_id"), "The selenium bug flag type is displayed but not selectable"); +$sel->select_ok("component", "label=c1"); +$sel->is_editable_ok("flag_type-$flagtype1_id", "The selenium bug flag type is not selectable"); +$sel->select_ok("flag_type-$flagtype1_id", "label=?"); +my $bug_summary2 = "Create a new selenium flag for c2"; +$sel->type_ok("short_desc", $bug_summary2); +$sel->type_ok("comment", "."); +my $bug2_id = create_bug($sel, $bug_summary2); + +$sel->is_text_present_ok("$config->{admin_user_username}: selenium"); +my $flag2_id = $sel->get_attribute('//select[@title="Available in TestProduct and Another Product/c1"]@id'); +$flag2_id =~ s/flag-//; +$sel->selected_label_is("flag-$flag2_id", '?'); + +# Create a 2nd bug flag type, again named 'selenium', but now +# for the 'Another Product / c2' component only. + +go_to_admin($sel); +$sel->click_ok("link=Flags"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Administer Flag Types"); +$sel->click_ok("link=Create Flag Type for Bugs"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Create Flag Type for Bugs"); +$sel->type_ok("name", "selenium"); +$sel->type_ok("description", "Another flag with the selenium name"); +$sel->add_selection_ok("inclusion_to_remove", "label=__Any__:__Any__"); +$sel->click_ok("categoryAction-removeInclusion"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Create Flag Type for Bugs"); +$sel->select_ok("product", "label=Another Product"); +$sel->select_ok("component", "label=c2"); +$sel->click_ok("categoryAction-include"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Create Flag Type for Bugs"); +$sel->type_ok("sortkey", 50); +$sel->value_is("is_active", "on"); +$sel->value_is("is_requestable", "on"); +$sel->value_is("is_multiplicable", "on"); +$sel->selected_label_is("grant_group", "(no group)"); +$sel->selected_label_is("request_group", "(no group)"); +$sel->click_ok("save"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Flag Type 'selenium' Created"); + +# Store the flag type ID. + +$sel->click_ok("link=selenium"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$flag_url = $sel->get_location(); +$flag_url =~ /id=(\d+)/; +my $flagtype2_id = $1; + +# Now move the bug from c1 into c2. The bug flag should survive. + +go_to_bug($sel, $bug2_id); +$sel->select_ok("component", "label=c2"); +ok(!$sel->is_checked("set_default_assignee"), "Moving the bug into another component must not change the assignee"); +$sel->type_ok("comment", "The selenium flag should be preserved."); +edit_bug_and_return($sel, $bug2_id, $bug_summary2); +$sel->selected_label_is("flag-$flag2_id", '?'); +ok(!$sel->is_element_present("flag_type-$flagtype1_id"), "Flag type not available in component c2"); +$sel->is_element_present_ok("flag_type-$flagtype2_id"); +logout($sel); + +# Powerless users can edit the 'selenium' flag being in c2. + +log_in($sel, $config, 'unprivileged'); +go_to_bug($sel, $bug2_id); +$sel->select_ok("flag-$flag2_id", "label=+"); +edit_bug_and_return($sel, $bug2_id, $bug_summary2); +$sel->selected_label_is("flag-$flag2_id", "+"); + +# But moving the bug into TestProduct will delete the flag +# as the flag setter is not in the editbugs group. + +$sel->select_ok("product", "label=TestProduct"); +$sel->type_ok("comment", "selenium flag will be lost. I don't have editbugs privs."); +$sel->click_ok("commit"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Verify New Product Details..."); +edit_bug_and_return($sel, $bug2_id, $bug_summary2, {id => "change_product"}); +ok(!$sel->is_element_present("flag-$flag2_id"), "Flag $flag2_id deleted"); +ok(!$sel->is_element_present("flag_type-$flagtype1_id"), "Flag type 'selenium' not displayed to powerless users"); +ok(!$sel->is_element_present("flag_type-$flagtype2_id"), "Flag type not available in component c1"); +logout($sel); + +# Time to delete created flag types. + +log_in($sel, $config, 'admin'); +go_to_admin($sel); +$sel->click_ok("link=Flags"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Administer Flag Types"); + +foreach my $flagtype ([$flagtype1_id, "selenium"], [$flagtype2_id, "selenium"], + [$aflagtype1_id, "selenium_review"], [$aflagtype2_id, "selenium_review"]) +{ + my $flag_id = $flagtype->[0]; + my $flag_name = $flagtype->[1]; + $sel->click_ok("//a[\@href='editflagtypes.cgi?action=confirmdelete&id=$flag_id']"); + $sel->wait_for_page_to_load_ok(WAIT_TIME); + $sel->title_is("Confirm Deletion of Flag Type '$flag_name'"); + $sel->click_ok("link=Yes, delete"); + $sel->wait_for_page_to_load_ok(WAIT_TIME); + $sel->title_is("Flag Type '$flag_name' Deleted"); + my $msg = trim($sel->get_text("message")); + ok($msg eq "The flag type $flag_name has been deleted.", "Flag type $flag_name deleted"); +} +logout($sel); diff --git a/xt/selenium/groups.t b/xt/selenium/groups.t new file mode 100644 index 000000000..b755cafc8 --- /dev/null +++ b/xt/selenium/groups.t @@ -0,0 +1,378 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# This Source Code Form is "Incompatible With Secondary Licenses", as +# defined by the Mozilla Public License, v. 2.0. + +use 5.10.1; +use strict; +use warnings; + +use FindBin qw($RealBin); +use lib "$RealBin/../lib"; + +use Test::More "no_plan"; + +use QA::Util; + +my ($sel, $config) = get_selenium(); + +# Add the new Selenium-test group. + +log_in($sel, $config, 'admin'); +go_to_admin($sel); +$sel->click_ok("link=Groups"); +$sel->wait_for_page_to_load(WAIT_TIME); +$sel->title_is("Edit Groups"); +$sel->click_ok("link=Add Group"); +$sel->wait_for_page_to_load(WAIT_TIME); +$sel->title_is("Add group"); +$sel->type_ok("name", "Selenium-test"); +$sel->type_ok("desc", "Test group for Selenium"); +$sel->check_ok("isactive"); +$sel->uncheck_ok("insertnew"); +$sel->click_ok("create"); +$sel->wait_for_page_to_load(WAIT_TIME); +$sel->title_is("New Group Created"); +my $group_id = $sel->get_value("group_id"); + +# Mark the Selenium-test group as Shown/Mandatory for TestProduct. + +edit_product($sel, "TestProduct"); +$sel->click_ok("link=Edit Group Access Controls:"); +$sel->wait_for_page_to_load(WAIT_TIME); +$sel->title_is("Edit Group Controls for TestProduct"); +$sel->is_text_present_ok("Selenium-test"); +$sel->select_ok("membercontrol_${group_id}", "label=Shown"); +$sel->select_ok("othercontrol_${group_id}", "label=Mandatory"); +$sel->click_ok("submit"); +$sel->wait_for_page_to_load(WAIT_TIME); +$sel->title_is("Update group access controls for TestProduct"); + +# File a new bug in the TestProduct product, and restrict it to the bug group. + +file_bug_in_product($sel, "TestProduct"); +$sel->is_text_present_ok("Test group for Selenium"); +$sel->value_is("group_${group_id}", "off"); # Must be OFF (else that's a bug) +$sel->check_ok("group_${group_id}"); +my $bug_summary = "bug restricted to the Selenium group"; +$sel->type_ok("short_desc", $bug_summary); +$sel->type_ok("comment", "should be invisible"); +$sel->selected_label_is("component", "TestComponent"); +my $bug1_id = create_bug($sel, $bug_summary); +$sel->is_text_present_ok("Test group for Selenium"); +$sel->value_is("group_${group_id}", "on"); # Must be ON + +# Look for this new bug and add it to the new "Selenium bugs" saved search. + +open_advanced_search_page($sel); +$sel->remove_all_selections_ok("product"); +$sel->add_selection_ok("product", "TestProduct"); +$sel->remove_all_selections("bug_status"); +$sel->add_selection_ok("bug_status", "UNCONFIRMED"); +$sel->add_selection_ok("bug_status", "CONFIRMED"); +$sel->select_ok("f1", "Group"); +$sel->select_ok("o1", "is equal to"); +$sel->type_ok("v1", "Selenium-test"); +$sel->click_ok("Search"); +$sel->wait_for_page_to_load(WAIT_TIME); +$sel->title_is("Bug List"); +$sel->is_text_present_ok("One bug found"); +$sel->is_text_present_ok("bug restricted to the Selenium group"); +$sel->type_ok("save_newqueryname", "Selenium bugs"); +$sel->click_ok("remember"); +$sel->wait_for_page_to_load(WAIT_TIME); +$sel->is_text_present_ok("OK, you have a new search named Selenium bugs"); +$sel->click_ok("link=Selenium bugs"); +$sel->wait_for_page_to_load(WAIT_TIME); +$sel->title_is("Bug List: Selenium bugs"); +$sel->is_text_present_ok("One bug found"); +$sel->is_element_present_ok("b$bug1_id", undef, "Bug $bug1_id restricted to the bug group"); + +# No longer use Selenium-test as a bug group. + +go_to_admin($sel); +$sel->click_ok("link=Groups"); +$sel->wait_for_page_to_load(WAIT_TIME); +$sel->title_is("Edit Groups"); +$sel->click_ok("link=Selenium-test"); +$sel->wait_for_page_to_load(WAIT_TIME); +$sel->title_is("Change Group: Selenium-test"); +$sel->value_is("isactive", "on"); +$sel->click_ok("isactive"); +$sel->click_ok('//input[@value="Update Group"]'); +$sel->wait_for_page_to_load(WAIT_TIME); +$sel->title_is("Change Group: Selenium-test"); +$sel->is_text_present_ok("The group will no longer be used for bugs"); + +# File another new bug, now visible as the bug group is disabled. + +file_bug_in_product($sel, "TestProduct"); +$sel->selected_label_is("component", "TestComponent"); +my $bug_summary2 = "bug restricted to the Selenium group"; +$sel->type_ok("short_desc", $bug_summary2); +$sel->type_ok("comment", "should be *visible* when created (the group is disabled)"); +ok(!$sel->is_text_present("Test group for Selenium"), "Selenium-test group unavailable"); +ok(!$sel->is_element_present("group_${group_id}"), "Selenium-test checkbox not present"); +my $bug2_id = create_bug($sel, $bug_summary2); + +# Make sure the new bug doesn't appear in the "Selenium bugs" saved search. + +$sel->click_ok("link=Selenium bugs"); +$sel->wait_for_page_to_load(WAIT_TIME); +$sel->title_is("Bug List: Selenium bugs"); +$sel->is_text_present_ok("One bug found"); +$sel->is_element_present_ok("b$bug1_id", undef, "Bug $bug1_id restricted to the bug group"); +ok(!$sel->is_element_present("b$bug2_id"), "Bug $bug2_id NOT restricted to the bug group"); + +# Re-enable the Selenium-test group as bug group. This doesn't affect +# already filed bugs as this group is not mandatory. + +go_to_admin($sel); +$sel->click_ok("link=Groups"); +$sel->wait_for_page_to_load(WAIT_TIME); +$sel->title_is("Edit Groups"); +$sel->click_ok("link=Selenium-test"); +$sel->wait_for_page_to_load(WAIT_TIME); +$sel->value_is("isactive", "off"); +$sel->click_ok("isactive"); +$sel->title_is("Change Group: Selenium-test"); +$sel->click_ok('//input[@value="Update Group"]'); +$sel->wait_for_page_to_load(WAIT_TIME); +$sel->title_is("Change Group: Selenium-test"); +$sel->is_text_present_ok("The group will now be used for bugs"); + +# Make sure the second filed bug has not been added to the bug group. + +$sel->click_ok("link=Selenium bugs"); +$sel->wait_for_page_to_load(WAIT_TIME); +$sel->title_is("Bug List: Selenium bugs"); +$sel->is_text_present_ok("One bug found"); +$sel->is_element_present_ok("b$bug1_id", undef, "Bug $bug1_id restricted to the bug group"); +ok(!$sel->is_element_present("b$bug2_id"), "Bug $bug2_id NOT restricted to the bug group"); + +# Make the Selenium-test group mandatory for TestProduct. + +edit_product($sel, "TestProduct"); +$sel->is_text_present_ok("Selenium-test:Shown/Mandatory"); +$sel->click_ok("link=Edit Group Access Controls:"); +$sel->wait_for_page_to_load(WAIT_TIME); +$sel->select_ok("membercontrol_${group_id}", "Mandatory"); +$sel->click_ok("submit"); +$sel->wait_for_page_to_load(WAIT_TIME); +$sel->title_is("Confirm Group Control Change for product 'TestProduct'"); +$sel->is_text_present_ok("this group is mandatory and will be added"); +$sel->click_ok("update"); +$sel->wait_for_page_to_load(WAIT_TIME); +$sel->title_is("Update group access controls for TestProduct"); +$sel->is_text_present_ok('regexp:Adding bugs to group \'Selenium-test\' which is now mandatory for this product'); + +# All bugs being in TestProduct must now be restricted to the bug group. + +$sel->click_ok("link=Selenium bugs"); +$sel->wait_for_page_to_load(WAIT_TIME); +$sel->title_is("Bug List: Selenium bugs"); +$sel->is_element_present_ok("b$bug1_id", undef, "Bug $bug1_id restricted to the bug group"); +$sel->is_element_present_ok("b$bug2_id", undef, "Bug $bug2_id restricted to the bug group"); + +# File a new bug, which must automatically be restricted to the bug group. + +file_bug_in_product($sel, "TestProduct"); +$sel->selected_label_is("component", "TestComponent"); +my $bug_summary3 = "Selenium-test group mandatory"; +$sel->type_ok("short_desc", $bug_summary3); +$sel->type_ok("comment", "group enabled"); +ok(!$sel->is_text_present("Test group for Selenium"), "Selenium-test group not available"); +ok(!$sel->is_element_present("group_${group_id}"), "Selenium-test checkbox not present (mandatory group)"); +my $bug3_id = create_bug($sel, $bug_summary3); + +# Make sure all three bugs are listed as being restricted to the bug group. + +$sel->click_ok("link=Selenium bugs"); +$sel->wait_for_page_to_load(WAIT_TIME); +$sel->title_is("Bug List: Selenium bugs"); +$sel->is_element_present_ok("b$bug1_id", undef, "Bug $bug1_id restricted to the bug group"); +$sel->is_element_present_ok("b$bug2_id", undef, "Bug $bug2_id restricted to the bug group"); +$sel->is_element_present_ok("b$bug3_id", undef, "Bug $bug3_id restricted to the bug group"); + +# Turn off the Selenium-test group again. + +go_to_admin($sel); +$sel->click_ok("link=Groups"); +$sel->wait_for_page_to_load(WAIT_TIME); +$sel->title_is("Edit Groups"); +$sel->click_ok("link=Selenium-test"); +$sel->wait_for_page_to_load(WAIT_TIME); +$sel->title_is("Change Group: Selenium-test"); +$sel->value_is("isactive", "on"); +$sel->click_ok("isactive"); +$sel->click_ok("//input[\@value='Update Group']"); +$sel->wait_for_page_to_load(WAIT_TIME); +$sel->title_is("Change Group: Selenium-test"); +$sel->is_text_present_ok("The group will no longer be used for bugs"); + +# File a bug again. It should not be added to the bug group as this one is disabled. + +file_bug_in_product($sel, "TestProduct"); +$sel->selected_label_is("component", "TestComponent"); +my $bug_summary4 = "bug restricted to the Selenium-test group"; +$sel->type_ok("short_desc", $bug_summary4); +$sel->type_ok("comment", "group disabled"); +ok(!$sel->is_text_present("Test group for Selenium"), "Selenium-test group not available"); +ok(!$sel->is_element_present("group_${group_id}"), "Selenium-test checkbox not present"); +my $bug4_id = create_bug($sel, $bug_summary4); + +# The last bug must not be in the list. + +$sel->click_ok("link=Selenium bugs"); +$sel->wait_for_page_to_load(WAIT_TIME); +$sel->title_is("Bug List: Selenium bugs"); +$sel->is_element_present_ok("b$bug1_id", undef, "Bug $bug1_id restricted to the bug group"); +$sel->is_element_present_ok("b$bug2_id", undef, "Bug $bug2_id restricted to the bug group"); +$sel->is_element_present_ok("b$bug3_id", undef, "Bug $bug3_id restricted to the bug group"); +ok(!$sel->is_element_present("b$bug4_id"), "Bug $bug4_id NOT restricted to the bug group"); + +# Re-enable the mandatory group. All bugs should be restricted to this bug group automatically. + +go_to_admin($sel); +$sel->click_ok("link=Groups"); +$sel->wait_for_page_to_load(WAIT_TIME); +$sel->title_is("Edit Groups"); +$sel->click_ok("link=Selenium-test"); +$sel->wait_for_page_to_load(WAIT_TIME); +$sel->title_is("Change Group: Selenium-test"); +$sel->value_is("isactive", "off"); +$sel->click_ok("isactive"); +$sel->click_ok("//input[\@value='Update Group']"); +$sel->wait_for_page_to_load(WAIT_TIME); +$sel->title_is("Change Group: Selenium-test"); +$sel->is_text_present_ok("The group will now be used for bugs"); + +# Make sure all bugs are restricted to the bug group. + +$sel->click_ok("link=Selenium bugs"); +$sel->wait_for_page_to_load(WAIT_TIME); +$sel->title_is("Bug List: Selenium bugs"); +$sel->is_element_present_ok("b$bug1_id", undef, "Bug $bug1_id restricted to the bug group"); +$sel->is_element_present_ok("b$bug2_id", undef, "Bug $bug2_id restricted to the bug group"); +$sel->is_element_present_ok("b$bug3_id", undef, "Bug $bug3_id restricted to the bug group"); +$sel->is_element_present_ok("b$bug4_id", undef, "Bug $bug4_id restricted to the bug group"); + +# Try to remove the Selenium-test group from TestProduct, but DON'T do it! +# We just want to make sure a warning is displayed about this removal. + +edit_product($sel, "TestProduct"); +$sel->is_text_present_ok("Selenium-test:Mandatory/Mandatory"); +$sel->click_ok("link=Edit Group Access Controls:"); +$sel->wait_for_page_to_load(WAIT_TIME); +$sel->title_is("Edit Group Controls for TestProduct"); +$sel->is_text_present_ok("Selenium-test"); +$sel->select_ok("membercontrol_${group_id}", "NA"); +$sel->select_ok("othercontrol_${group_id}", "NA"); +$sel->click_ok("submit"); +$sel->wait_for_page_to_load(WAIT_TIME); +$sel->title_is("Confirm Group Control Change for product 'TestProduct'"); +$sel->is_text_present_ok("this group is no longer applicable and will be removed"); + +# Make sure that renaming a group which is used as a special group +# (such as insidergroup or querysharegroup) is correctly propagated +# and that you cannot delete this group. + +set_parameters($sel, { "Group Security" => {"querysharegroup" => {type => "select", value => "Selenium-test"}} }); + +go_to_admin($sel); +$sel->click_ok("link=Groups"); +$sel->wait_for_page_to_load(WAIT_TIME); +$sel->title_is("Edit Groups"); +$sel->click_ok("link=Selenium-test"); +$sel->wait_for_page_to_load(WAIT_TIME); +$sel->title_is("Change Group: Selenium-test"); +$sel->type_ok("name", "X-Selenium-Y"); +$sel->click_ok("update-group"); +$sel->wait_for_page_to_load(WAIT_TIME); +$sel->title_is("Change Group: X-Selenium-Y"); +$sel->is_text_present_ok("The name was changed to 'X-Selenium-Y'"); + +go_to_admin($sel); +$sel->click_ok("link=Parameters"); +$sel->wait_for_page_to_load(WAIT_TIME); +$sel->title_is("Configuration: Required Settings"); +$sel->click_ok("link=Group Security"); +$sel->wait_for_page_to_load(WAIT_TIME); +$sel->title_is("Configuration: Group Security"); +$sel->value_is("querysharegroup", "X-Selenium-Y"); + +# There is no UI to delete this group, so we have to type the URL directly. + +$sel->open_ok("/$config->{bugzilla_installation}/editgroups.cgi?action=del&group=$group_id"); +$sel->title_is("Group not deletable"); +$sel->is_text_present_ok("The group 'X-Selenium-Y' is used by the 'querysharegroup' parameter"); + +$sel->open_ok("/$config->{bugzilla_installation}/editgroups.cgi?action=delete&group=$group_id"); +$sel->title_is("Suspicious Action"); +$sel->is_text_present_ok("you have no valid token for the delete_group action while processing the 'editgroups.cgi' script"); +$sel->click_ok("confirm"); +$sel->wait_for_page_to_load(WAIT_TIME); +$sel->title_is("Group not deletable"); +$sel->is_text_present_ok("The group 'X-Selenium-Y' is used by the 'querysharegroup' parameter"); + +set_parameters($sel, { "Group Security" => {"querysharegroup" => {type => "select", value => ""}} }); + +# Revert the group name change to not mess with the subsequent tests +# which expect to see 'Selenium-test'. + +go_to_admin($sel); +$sel->click_ok("link=Groups"); +$sel->wait_for_page_to_load(WAIT_TIME); +$sel->title_is("Edit Groups"); +$sel->click_ok("link=X-Selenium-Y"); +$sel->wait_for_page_to_load(WAIT_TIME); +$sel->title_is("Change Group: X-Selenium-Y"); +$sel->type_ok("name", "Selenium-test"); +$sel->click_ok("update-group"); +$sel->wait_for_page_to_load(WAIT_TIME); +$sel->title_is("Change Group: Selenium-test"); +$sel->is_text_present_ok("The name was changed to 'Selenium-test'"); + +# Delete the Selenium-test group. + +go_to_admin($sel); +$sel->click_ok("link=Groups"); +$sel->wait_for_page_to_load(WAIT_TIME); +$sel->title_is("Edit Groups"); +$sel->click_ok("//a[\@href='editgroups.cgi?action=del&group=${group_id}']"); +$sel->wait_for_page_to_load(WAIT_TIME); +$sel->title_like(qr/^Delete group/); +$sel->is_text_present_ok("Do you really want to delete this group?"); +$sel->is_element_present_ok("removebugs"); +$sel->value_is("removebugs", "off"); +$sel->is_text_present_ok("Remove all bugs from this group restriction for me"); +$sel->is_element_present_ok("unbind"); +$sel->value_is("unbind", "off"); +$sel->is_text_present_ok("remove these controls"); +$sel->click_ok("delete"); +$sel->wait_for_page_to_load(WAIT_TIME); +$sel->title_is("Cannot Delete Group"); +my $error_msg = trim($sel->get_text("error_msg")); +ok($error_msg =~ /^The Selenium-test group cannot be deleted/, "Group is in use - not deletable"); +$sel->go_back_ok(); +$sel->wait_for_page_to_load(WAIT_TIME); +$sel->check("removebugs"); +$sel->check("unbind"); +$sel->click_ok("delete"); +$sel->wait_for_page_to_load(WAIT_TIME); +$sel->title_is("Group Deleted"); +$sel->is_text_present_ok("The group Selenium-test has been deleted."); + +# No more bugs listed in the saved search as the bug group is gone. + +$sel->click_ok("link=Selenium bugs"); +$sel->wait_for_page_to_load(WAIT_TIME); +$sel->title_is("Bug List: Selenium bugs"); +$sel->is_text_present_ok("Zarro Boogs found"); +$sel->click_ok("forget_search"); +$sel->wait_for_page_to_load(WAIT_TIME); +$sel->title_is("Search is gone"); +$sel->is_text_present_ok("OK, the Selenium bugs search is gone."); +logout($sel); diff --git a/xt/selenium/keywords.t b/xt/selenium/keywords.t new file mode 100644 index 000000000..16ecf90e7 --- /dev/null +++ b/xt/selenium/keywords.t @@ -0,0 +1,181 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# This Source Code Form is "Incompatible With Secondary Licenses", as +# defined by the Mozilla Public License, v. 2.0. + +use 5.10.1; +use strict; +use warnings; + +use FindBin qw($RealBin); +use lib "$RealBin/../lib"; + +use Test::More "no_plan"; + +use QA::Util; + +my ($sel, $config) = get_selenium(); + +# Create keywords. Do some cleanup first if necessary. + +log_in($sel, $config, 'admin'); +go_to_admin($sel); +$sel->click_ok("link=Keywords"); +$sel->wait_for_page_to_load(WAIT_TIME); +$sel->title_is("Select keyword"); + +# If keywords already exist, delete them to not disturb the test. + +my $page = $sel->get_body_text(); +my @keywords = $page =~ m/(key-selenium-\w+)/gi; + +foreach my $keyword (@keywords) { + my $url = $sel->get_attribute("link=$keyword\@href"); + $url =~ s/action=edit/action=del/; + $sel->click_ok("//a[\@href='$url']"); + $sel->wait_for_page_to_load(WAIT_TIME); + $sel->title_is("Delete Keyword"); + $sel->click_ok("delete"); + $sel->wait_for_page_to_load(WAIT_TIME); + $sel->title_is("Keyword Deleted"); +} + +# Now let's create our first keyword. + +go_to_admin($sel); +$sel->click_ok("link=Keywords"); +$sel->wait_for_page_to_load(WAIT_TIME); +$sel->title_is("Select keyword"); +$sel->click_ok("link=Add a new keyword"); +$sel->wait_for_page_to_load(WAIT_TIME); +$sel->title_is("Add keyword"); +$sel->type_ok("name", "key-selenium-kone"); +$sel->type_ok("description", "Hopefully an ice cream"); +$sel->click_ok("create"); +$sel->wait_for_page_to_load(WAIT_TIME); +$sel->title_is("New Keyword Created"); + +# Try create the same keyword, to check validators. + +$sel->click_ok("link=Add a new keyword"); +$sel->wait_for_page_to_load(WAIT_TIME); +$sel->title_is("Add keyword"); +$sel->type_ok("name", "key-selenium-kone"); +$sel->type_ok("description", "FIX ME!"); +$sel->click_ok("create"); +$sel->wait_for_page_to_load(WAIT_TIME); +$sel->title_is("Keyword Already Exists"); +my $error_msg = trim($sel->get_text("error_msg")); +ok($error_msg eq 'A keyword with the name key-selenium-kone already exists.', 'Already created keyword'); +$sel->go_back_ok(); +$sel->wait_for_page_to_load(WAIT_TIME); + +# Create a second keyword. + +$sel->type_ok("name", "key-selenium-ktwo"); +$sel->type_ok("description", "FIX ME!"); +$sel->click_ok("create"); +$sel->wait_for_page_to_load(WAIT_TIME); +$sel->title_is("New Keyword Created"); + +# Again test validators. + +$sel->click_ok("link=key-selenium-ktwo"); +$sel->wait_for_page_to_load(WAIT_TIME); +$sel->title_is("Edit keyword"); +$sel->type_ok("name", "key-selenium-kone"); +$sel->type_ok("description", "the second keyword"); +$sel->click_ok("update"); +$sel->wait_for_page_to_load(WAIT_TIME); +$sel->title_is("Keyword Already Exists"); +$error_msg = trim($sel->get_text("error_msg")); +ok($error_msg eq 'A keyword with the name key-selenium-kone already exists.', 'Already created keyword'); +$sel->go_back_ok(); +$sel->wait_for_page_to_load(WAIT_TIME); +$sel->title_is("Edit keyword"); +$sel->type_ok("name", "key-selenium-ktwo"); +$sel->click_ok("update"); +$sel->wait_for_page_to_load(WAIT_TIME); +$sel->title_is("Keyword Updated"); + +# Add keywords to bugs + +file_bug_in_product($sel, "TestProduct"); +$sel->select_ok("component", "TestComponent"); +$sel->type_ok("keywords", "key-selenium-kone"); +my $bug_summary = "It's a beautiful day"; +$sel->type_ok("short_desc", $bug_summary); +$sel->type_ok("comment", "This bug is to test keywords"); +my $bug1_id = create_bug($sel, $bug_summary); + +file_bug_in_product($sel, "TestProduct"); +$sel->select_ok("component", "TestComponent"); +$sel->type_ok("keywords", "key-selenium-kone, key-selenium-ktwo"); +my $bug_summary2 = "Radio gaga"; +$sel->type_ok("short_desc", $bug_summary2); +$sel->type_ok("comment", "This bug is also to test keywords, like bug $bug1_id"); +my $bug2_id = create_bug($sel, $bug_summary2); + +# Now make sure these bugs correctly appear in buglists. + +open_advanced_search_page($sel); +$sel->remove_all_selections("product"); +$sel->remove_all_selections("bug_status"); +$sel->type_ok("keywords", "key-selenium-kone"); +$sel->click_ok("Search"); +$sel->wait_for_page_to_load(WAIT_TIME); +$sel->title_is("Bug List"); +$sel->is_text_present_ok("2 bugs found"); + +$sel->click_ok("link=Search"); +$sel->wait_for_page_to_load(WAIT_TIME); +$sel->title_is("Search for bugs"); +$sel->remove_all_selections("product"); +$sel->remove_all_selections("bug_status"); +# Try with a different case than the one in the DB. +$sel->type_ok("keywords", "key-selenium-ktWO"); +$sel->click_ok("Search"); +$sel->wait_for_page_to_load(WAIT_TIME); +$sel->title_is("Bug List"); +$sel->is_text_present_ok("One bug found"); + +$sel->click_ok("link=Search"); +$sel->wait_for_page_to_load(WAIT_TIME); +$sel->title_is("Search for bugs"); +$sel->remove_all_selections("product"); +$sel->remove_all_selections("bug_status"); +# Substrings also work for keywords. +$sel->type_ok("keywords", "selenium"); +$sel->click_ok("Search"); +$sel->wait_for_page_to_load(WAIT_TIME); +$sel->title_is("Bug List"); +$sel->is_text_present_ok("2 bugs found"); + +# Make sure describekeywords.cgi works as expected. + +$sel->click_ok("link=$bug_summary"); +$sel->wait_for_page_to_load(WAIT_TIME); +$sel->title_like(qr/^$bug1_id /); +$sel->click_ok("link=Keywords:"); +$sel->wait_for_page_to_load(WAIT_TIME); +$sel->title_is("Bugzilla Keyword Descriptions"); +$sel->is_text_present_ok("key-selenium-kone"); +$sel->is_text_present_ok("Hopefully an ice cream"); +$sel->is_text_present_ok("key-selenium-ktwo"); +$sel->is_text_present_ok("the second keyword"); +$sel->click_ok('//a[@href="buglist.cgi?keywords=key-selenium-kone"]'); +$sel->wait_for_page_to_load(WAIT_TIME); +$sel->title_is("Bug List"); +$sel->is_element_present_ok("link=$bug1_id"); +$sel->is_element_present_ok("link=$bug2_id"); +$sel->is_text_present_ok("2 bugs found"); +$sel->go_back_ok(); +$sel->wait_for_page_to_load(WAIT_TIME); +$sel->click_ok('//a[@href="buglist.cgi?keywords=key-selenium-ktwo"]'); +$sel->wait_for_page_to_load(WAIT_TIME); +$sel->title_is("Bug List"); +$sel->is_element_present_ok("link=$bug2_id"); +$sel->is_text_present_ok("One bug found"); +logout($sel); diff --git a/xt/selenium/login.t b/xt/selenium/login.t new file mode 100644 index 000000000..b41d9a2d2 --- /dev/null +++ b/xt/selenium/login.t @@ -0,0 +1,37 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# This Source Code Form is "Incompatible With Secondary Licenses", as +# defined by the Mozilla Public License, v. 2.0. + +use 5.10.1; +use strict; +use warnings; + +use FindBin qw($RealBin); +use lib "$RealBin/../lib"; + +use Test::More "no_plan"; + +use QA::Util; + +my ($sel, $config) = get_selenium(); + +# FIXME - At some point, this trivial script should be merged with test_create_user_accounts.t. +# Either that or we should improve this script a lot. + +# Try to log in to Bugzilla using an invalid account. To be sure that the login form +# is triggered, we try to file a new bug. + +go_to_home($sel, $config); +$sel->click_ok("link=New"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Log in to Bugzilla"); +# The login and password are hardcoded here, because this account doesn't exist. +$sel->type_ok("Bugzilla_login", 'guest@foo.com'); +$sel->type_ok("Bugzilla_password", 'foo-bar-baz'); +$sel->click_ok("log_in"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Invalid Login Or Password"); +$sel->is_text_present_ok("The login or password you entered is not valid."); diff --git a/xt/selenium/milestones.t b/xt/selenium/milestones.t new file mode 100644 index 000000000..35991fbd2 --- /dev/null +++ b/xt/selenium/milestones.t @@ -0,0 +1,149 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# This Source Code Form is "Incompatible With Secondary Licenses", as +# defined by the Mozilla Public License, v. 2.0. + +use 5.10.1; +use strict; +use warnings; + +use FindBin qw($RealBin); +use lib "$RealBin/../lib"; + +use Test::More "no_plan"; + +use QA::Util; + +my ($sel, $config) = get_selenium(); + +# 1st step: turn on usetargetmilestone and letsubmitterchoosemilestone. + +log_in($sel, $config, 'admin'); +set_parameters($sel, {'Bug Fields' => {'usetargetmilestone-on' => undef}, + 'Bug Change Policies' => {'letsubmitterchoosemilestone-on' => undef}, + } + ); + +# 2nd step: Add the milestone "2.0" (with sortkey = 10) to the TestProduct product. + +edit_product($sel, "TestProduct"); +$sel->click_ok("link=Edit milestones:", undef, "Go to the Edit milestones page"); +$sel->wait_for_page_to_load(WAIT_TIME); +$sel->title_is("Select milestone of product 'TestProduct'", "Display milestones"); +$sel->click_ok("link=Add", undef, "Go add a new milestone"); +$sel->wait_for_page_to_load(WAIT_TIME); +$sel->title_is("Add Milestone to Product 'TestProduct'", "Enter new milestone"); +$sel->type_ok("milestone", "2.0", "Set its name to 2.0"); +$sel->type_ok("sortkey", "10", "Set its sortkey to 10"); +$sel->click_ok("create", undef, "Submit data"); +$sel->wait_for_page_to_load(WAIT_TIME); +# If the milestone already exists, that's not a big deal. So no special action +# is required in this case. +$sel->title_is("Milestone Created", "Milestone Created"); + +# 3rd step: file a new bug, leaving the milestone alone (should fall back to the default one). + +file_bug_in_product($sel, "TestProduct"); +$sel->selected_label_is("component", "TestComponent", "Component already selected (no other component defined)"); +$sel->selected_label_is("target_milestone", "---", "Default milestone selected"); +$sel->selected_label_is("version", "unspecified", "Version already selected (no other version defined)"); +my $bug_summary = "Target Milestone left to default"; +$sel->type_ok("short_desc", $bug_summary); +$sel->type_ok("comment", "Created by Selenium to test 'musthavemilestoneonaccept'"); +my $bug1_id = create_bug($sel, $bug_summary); + +# 4th step: edit the bug + +go_to_bug($sel, $bug1_id); +$sel->select_ok("bug_status", "label=IN_PROGRESS", "Change bug status to IN_PROGRESS"); +$sel->select_ok("target_milestone", "label=2.0", "Select a non-default milestone"); +edit_bug($sel, $bug1_id, $bug_summary); + +# 5th step: create another bug. + +file_bug_in_product($sel, "TestProduct"); +$sel->select_ok("target_milestone", "label=2.0", "Set the milestone to 2.0"); +$sel->selected_label_is("component", "TestComponent", "Component already selected (no other component defined)"); +$sel->selected_label_is("version", "unspecified", "Version already selected (no other version defined)"); +my $bug_summary2 = "Target Milestone set to non-default"; +$sel->type_ok("short_desc", $bug_summary2); +$sel->type_ok("comment", "Created by Selenium to test milestone support"); +my $bug2_id = create_bug($sel, $bug_summary2); + +# 6th step: edit the bug + +$sel->select_ok("bug_status", "label=IN_PROGRESS"); +edit_bug($sel, $bug2_id, $bug_summary2); + +# 7th step: test validation methods for milestones. + +go_to_admin($sel); +$sel->click_ok("link=milestones"); +$sel->wait_for_page_to_load(WAIT_TIME); +$sel->title_is("Edit milestones for which product?"); +$sel->click_ok("link=TestProduct"); +$sel->wait_for_page_to_load(WAIT_TIME); +$sel->title_is("Select milestone of product 'TestProduct'"); +$sel->click_ok("link=2.0"); +$sel->wait_for_page_to_load(WAIT_TIME); +$sel->title_is("Edit Milestone '2.0' of product 'TestProduct'"); +$sel->type_ok("milestone", "1.0"); +$sel->value_is("milestone", "1.0"); +$sel->click_ok("update"); +$sel->wait_for_page_to_load(WAIT_TIME); +$sel->title_is("Milestone Updated"); +$sel->click_ok("link=Add"); +$sel->wait_for_page_to_load(WAIT_TIME); +$sel->title_is("Add Milestone to Product 'TestProduct'"); +$sel->type_ok("milestone", "1.5"); +$sel->value_is("milestone", "1.5"); +$sel->type_ok("sortkey", "99999999999999999"); +$sel->value_is("sortkey", "99999999999999999"); +$sel->click_ok("create"); +$sel->wait_for_page_to_load(WAIT_TIME); +$sel->title_is("Invalid Milestone Sortkey"); +my $error_msg = trim($sel->get_text("error_msg")); +ok($error_msg =~ /^The sortkey '99999999999999999' is not in the range/, "Invalid sortkey"); +$sel->go_back_ok(); +$sel->wait_for_page_to_load(WAIT_TIME); +$sel->type_ok("sortkey", "-polu7A"); +$sel->value_is("sortkey", "-polu7A"); +$sel->click_ok("create"); +$sel->wait_for_page_to_load(WAIT_TIME); +$sel->title_is("Invalid Milestone Sortkey"); +$error_msg = trim($sel->get_text("error_msg")); +ok($error_msg =~ /^The sortkey '-polu7A' is not in the range/, "Invalid sortkey"); +$sel->go_back_ok(); +$sel->wait_for_page_to_load(WAIT_TIME); +$sel->click_ok("link='TestProduct'"); +$sel->wait_for_page_to_load(WAIT_TIME); +$sel->title_is("Select milestone of product 'TestProduct'"); +$sel->click_ok("link=Delete"); +$sel->wait_for_page_to_load(WAIT_TIME); +$sel->title_is("Delete Milestone of Product 'TestProduct'"); +$sel->is_text_present_ok("When you delete this milestone", undef, "Warn the user about bugs being affected"); +$sel->click_ok("delete"); +$sel->wait_for_page_to_load(WAIT_TIME); +$sel->title_is("Milestone Deleted"); + +# 8th step: make sure the (now deleted) milestone of the bug has fallen back to the default milestone. + +go_to_bug($sel, $bug1_id); +$sel->is_text_present_ok('regexp:Target Milestone:\W+---', undef, "Milestone has fallen back to the default milestone"); + +# 9th step: file another bug. + +file_bug_in_product($sel, "TestProduct"); +$sel->selected_label_is("target_milestone", "---", "Default milestone selected"); +$sel->selected_label_is("component", "TestComponent"); +my $bug_summary3 = "Only one Target Milestone available"; +$sel->type_ok("short_desc", $bug_summary3); +$sel->type_ok("comment", "Created by Selenium to test milestone support"); +my $bug3_id = create_bug($sel, $bug_summary3); + +$sel->select_ok("bug_status", "label=IN_PROGRESS"); +edit_bug($sel, $bug3_id, $bug_summary3); + +logout($sel); diff --git a/xt/selenium/password_complexity.t b/xt/selenium/password_complexity.t new file mode 100644 index 000000000..e29ef8bec --- /dev/null +++ b/xt/selenium/password_complexity.t @@ -0,0 +1,123 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# This Source Code Form is "Incompatible With Secondary Licenses", as +# defined by the Mozilla Public License, v. 2.0. + +use 5.10.1; +use strict; +use warnings; + +use FindBin qw($RealBin); +use lib "$RealBin/../lib"; + +use Test::More "no_plan"; + +use QA::Util; + +my ($sel, $config) = get_selenium(); +log_in($sel, $config, 'admin'); + +set_parameters($sel, {"Administrative Policies" => {"allowuserdeletion-on" => undef}, + "User Authentication" => {"createemailregexp" => {type => "text", value => '.*'}, + "emailsuffix" => {type => "text", value => ''}} }); + +# Set the password complexity to MIXED LETTERS. +# Password must contain at least one UPPER and one lowercase letter. +my @invalid_mixed_letter = qw(lowercase UPPERCASE 1234567890 123lowercase + 123UPPERCASE !@%&^lower !@&^UPPER); + +check_passwords($sel, 'mixed_letters', \@invalid_mixed_letter, ['PaSSwOrd', '%9rT#j22S']); + +# Set the password complexity to LETTERS AND NUMBERS. +# Passwords must contain at least one UPPER and one lower case letter and a number. +my @invalid_letter_number = (@invalid_mixed_letter, qw(lowerUPPER 123!@%^$)); + +check_passwords($sel, 'letters_numbers', \@invalid_letter_number, ['-UniCode6.3', 'UNO54sun']); + +# Set the password complexity to LETTERS, NUMBERS AND SPECIAL CHARACTERS. +# Passwords must contain at least one letter, a number and a special character. +my @invalid_letter_number_splchar = (qw(!@%^&~* lowerUPPER123), @invalid_letter_number); + +check_passwords($sel, 'letters_numbers_specialchars', \@invalid_letter_number_splchar, ['@gu731', 'HU%m70?']); + +# Set the password complexity to No Constraints. +check_passwords($sel, 'no_constraints', ['12xY!', 'aaaaa'], ['aaaaaaaa', '>F12Xy?']); + +logout($sel); + + +sub check_passwords { + my ($sel, $param, $invalid_passwords, $valid_passwords) = @_; + + set_parameters($sel, { "User Authentication" => {"password_complexity" => {type => "select", value => $param}} }); + my $new_user = 'selenium-' . random_string(10) . '@bugzilla.org'; + + go_to_admin($sel); + $sel->click_ok("link=Users"); + $sel->wait_for_page_to_load_ok(WAIT_TIME); + $sel->title_is('Search users'); + $sel->click_ok('link=add a new user'); + $sel->wait_for_page_to_load_ok(WAIT_TIME); + $sel->title_is('Add user'); + $sel->type_ok('login', $new_user); + + foreach my $password (@$invalid_passwords) { + $sel->type_ok('password', $password, 'Enter password'); + $sel->click_ok('add'); + $sel->wait_for_page_to_load_ok(WAIT_TIME); + if ($param eq 'no_constraints') { + $sel->title_is('Password Too Short'); + } + else { + $sel->title_is('Password Fails Requirements'); + } + + my $error_msg = trim($sel->get_text("error_msg")); + if ($param eq 'mixed_letters') { + ok($error_msg =~ /UPPERCASE letter.*lowercase letter/, + "Mixed letter password fails requirement: $password"); + } + elsif ($param eq 'letters_numbers') { + ok($error_msg =~ /UPPERCASE letter.*lowercase letter.*digit/, + "Letter & Number password fails requirement: $password"); + + } + elsif ($param eq 'letters_numbers_specialchars') { + ok($error_msg =~ /letter.*special character.*digit/, + "Letter, Number & Special Character password fails requirement: $password"); + } + else { + ok($error_msg =~ /The password must be at least \d+ characters long/, + "Password Too Short: $password"); + } + $sel->go_back_ok(); + $sel->wait_for_page_to_load_ok(WAIT_TIME); + } + + my $created = 0; + + foreach my $password (@$valid_passwords) { + $sel->type_ok('password', $password, 'Enter password'); + $sel->click_ok($created ? 'update' : 'add'); + $sel->wait_for_page_to_load_ok(WAIT_TIME); + $sel->title_is($created ? "User $new_user updated" : "Edit user $new_user"); + my $msg = trim($sel->get_text('message')); + if ($created++) { + ok($msg =~ /A new password has been set/, 'Account updated'); + } + else { + ok($msg =~ /The user account $new_user has been created successfully/, 'Account created'); + } + } + + return unless $created; + + $sel->click_ok('delete'); + $sel->wait_for_page_to_load_ok(WAIT_TIME); + $sel->title_is("Confirm deletion of user $new_user"); + $sel->click_ok('delete'); + $sel->wait_for_page_to_load_ok(WAIT_TIME); + $sel->title_is("User $new_user deleted"); +} diff --git a/xt/selenium/private_attachments.t b/xt/selenium/private_attachments.t new file mode 100644 index 000000000..4dacd26b3 --- /dev/null +++ b/xt/selenium/private_attachments.t @@ -0,0 +1,173 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# This Source Code Form is "Incompatible With Secondary Licenses", as +# defined by the Mozilla Public License, v. 2.0. + +use 5.10.1; +use strict; +use warnings; + +use FindBin qw($RealBin); +use lib "$RealBin/../lib"; + +use Test::More "no_plan"; + +use QA::Util; + +# We have to upload files from the local computer. This requires +# chrome privileges. +my ($sel, $config) = get_selenium(CHROME_MODE); + +# set the insidergroup parameter to the admin group, and make sure +# we can view and delete attachments. + +log_in($sel, $config, 'admin'); +set_parameters($sel, { "Group Security" => {"insidergroup" => {type => "select", value => "admin"}}, + "Attachments" => {"allow_attachment_display-on" => undef, + "allow_attachment_deletion-on" => undef} + }); + +# First create a new bug with a private attachment. + +file_bug_in_product($sel, "TestProduct"); +my $bug_summary = "Some comments are private"; +$sel->type_ok("short_desc", $bug_summary); +$sel->type_ok("comment", "and some attachments too, like this one."); +$sel->check_ok("comment_is_private"); +$sel->click_ok('//input[@value="Add an attachment"]'); +$sel->type_ok("data", $config->{attachment_file}); +$sel->type_ok("description", "private attachment, v1"); +$sel->check_ok("ispatch"); +my $bug1_id = create_bug($sel, $bug_summary); +$sel->is_text_present_ok("private attachment, v1 ("); +$sel->is_text_present_ok("and some attachments too, like this one."); +$sel->is_checked_ok('//a[@id="comment_link_0"]/../..//div//input[@type="checkbox"]'); + +# Now attach a public patch to the existing bug. + +$sel->click_ok("link=Add an attachment"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Create New Attachment for Bug #$bug1_id"); +$sel->type_ok("data", $config->{attachment_file}); +$sel->type_ok("description", "public attachment, v2"); +$sel->check_ok("ispatch"); +# The existing attachment name must be displayed, to mark it as obsolete. +$sel->is_text_present_ok("private attachment, v1"); +$sel->type_ok("comment", "this patch is public. Everyone can see it."); +$sel->value_is("isprivate", "off"); +edit_bug($sel, $bug1_id, $bug_summary, {id => "create"}); + +# We need to store the attachment ID. + +$sel->is_text_present_ok("public attachment, v2"); +my $alink = $sel->get_attribute('//a[@title="public attachment, v2"]@href'); +$alink =~ /id=(\d+)/; +my $attachment1_id = $1; +$sel->is_text_present_ok("this patch is public. Everyone can see it."); +ok(!$sel->is_checked('//a[@id="comment_link_1"]/../..//div//input[@type="checkbox"]'), "Public attachment is visible"); +logout($sel); + +# A logged out user cannot see the private attachment, only the public one. +# Same for a user with no privs. + +foreach my $user ('', 'unprivileged') { + log_in($sel, $config, $user) if $user; + go_to_bug($sel, $bug1_id); + ok(!$sel->is_text_present("private attachment, v1"), "Private attachment not visible"); + $sel->is_text_present_ok("public attachment, v2"); + ok(!$sel->is_text_present("and some attachments too, like this one"), "Private comment not visible"); + $sel->is_text_present_ok("this patch is public. Everyone can see it."); +} + +# A powerless user can comment on attachments he doesn't own. + +$sel->click_ok('//a[@href="attachment.cgi?id=' . $attachment1_id . '&action=edit"]'); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_like(qr/Attachment $attachment1_id Details for Bug $bug1_id/); +$sel->is_text_present_ok("created by admin"); +$sel->type_ok("comment", "This attachment is not mine."); +edit_bug($sel, $bug1_id, $bug_summary, {id => "update"}); +$sel->is_text_present_ok("This attachment is not mine"); + +# Powerless users will always be able to view their own attachments, even +# when those are marked private by a member of the insider group. + +$sel->click_ok("link=Add an attachment"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Create New Attachment for Bug #$bug1_id"); +$sel->type_ok("data", $config->{attachment_file}); +$sel->check_ok("ispatch"); +# The user doesn't have editbugs privs. +ok(!$sel->is_text_present("Check each existing attachment made obsolete by your new attachment"), "No attachments can be marked as obsolete"); +$sel->type_ok("description", "My patch, which I should see, always"); +$sel->type_ok("comment", "This is my patch!"); +edit_bug($sel, $bug1_id, $bug_summary, {id => "create"}); +$sel->is_text_present_ok("My patch, which I should see, always ("); +$alink = $sel->get_attribute('//a[@title="My patch, which I should see, always"]@href'); +$alink =~ /id=(\d+)/; +my $attachment2_id = $1; +$sel->is_text_present_ok("This is my patch!"); +logout($sel); + +# Let the admin mark the powerless user's attachment as private. + +log_in($sel, $config, 'admin'); +go_to_bug($sel, $bug1_id); +$sel->click_ok('//a[@href="attachment.cgi?id=' . $attachment2_id . '&action=edit"]'); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_like(qr/Attachment $attachment2_id Details for Bug $bug1_id/); +$sel->check_ok("isprivate"); +$sel->type_ok("comment", "Making the powerless user's patch private."); +edit_bug($sel, $bug1_id, $bug_summary, {id => "update"}); +$sel->is_text_present_ok("My patch, which I should see, always ("); +$sel->is_checked_ok('//a[@id="comment_link_4"]/../..//div//input[@type="checkbox"]'); +$sel->is_text_present_ok("Making the powerless user's patch private."); +logout($sel); + +# A logged out user cannot see private attachments. + +go_to_bug($sel, $bug1_id); +ok(!$sel->is_text_present("private attachment, v1"), "Private attachment not visible to logged out users"); +ok(!$sel->is_text_present("My patch, which I should see, always ("), "Private attachment not visible to logged out users"); +$sel->is_text_present_ok("This is my patch!"); +ok(!$sel->is_text_present("Making the powerless user's patch private"), "Private comment not visible to logged out users"); + +# A powerless user can only see private attachments he owns. + +log_in($sel, $config, 'unprivileged'); +go_to_bug($sel, $bug1_id); +$sel->is_text_present_ok("My patch, which I should see, always ("); +$sel->click_ok("link=My patch, which I should see, always"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +# No title displayed while viewing an attachment. +$sel->title_is(""); +$sel->go_back_ok(); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +logout($sel); + +# Admins can delete attachments. + +log_in($sel, $config, 'admin'); +go_to_bug($sel, $bug1_id); +$sel->click_ok('//a[@href="attachment.cgi?id=' . $attachment2_id . '&action=edit"]'); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_like(qr/Attachment $attachment2_id Details for Bug $bug1_id/); +$sel->click_ok("link=Delete"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Delete Attachment $attachment2_id of Bug $bug1_id"); +$sel->is_text_present_ok("Do you really want to delete this attachment?"); +$sel->type_ok("reason", "deleted by Selenium"); +edit_bug_and_return($sel, $bug1_id, $bug_summary, {id => "delete"}); +$sel->is_text_present_ok("deleted by Selenium"); +$sel->click_ok("link=attachment $attachment2_id"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Attachment Removed"); +$sel->is_text_present_ok("The attachment you are attempting to access has been removed"); + +set_parameters($sel, { + "Group Security" => {"insidergroup" => { type => "select", + value => "QA-Selenium-TEST" }}, +}); +logout($sel); diff --git a/xt/selenium/qa_contact.t b/xt/selenium/qa_contact.t new file mode 100644 index 000000000..c548a7182 --- /dev/null +++ b/xt/selenium/qa_contact.t @@ -0,0 +1,164 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# This Source Code Form is "Incompatible With Secondary Licenses", as +# defined by the Mozilla Public License, v. 2.0. + +use 5.10.1; +use strict; +use warnings; + +use FindBin qw($RealBin); +use lib "$RealBin/../lib"; + +use Test::More "no_plan"; + +use QA::Util; + +my ($sel, $config) = get_selenium(); + +# First make sure the 'My QA query' saved search is gone. + +log_in($sel, $config, 'admin'); +if ($sel->is_text_present("My QA query")) { + $sel->click_ok("link=My QA query"); + $sel->wait_for_page_to_load_ok(WAIT_TIME); + $sel->title_is("Bug List: My QA query"); + $sel->click_ok("forget_search"); + $sel->wait_for_page_to_load_ok(WAIT_TIME); + $sel->title_is("Search is gone"); + $sel->is_text_present_ok("OK, the My QA query search is gone."); +} + +# Enable the QA contact field and file a new bug restricted to the 'Master' group +# with a powerless user as the QA contact. He should only be able to access the +# bug if the QA contact field is enabled, else he looses this privilege. + +set_parameters($sel, { "Bug Fields" => {"useqacontact-on" => undef} }); +file_bug_in_product($sel, 'TestProduct'); +$sel->type_ok("qa_contact", $config->{unprivileged_user_login}, "Set the powerless user as QA contact"); +my $bug_summary = "Test for QA contact"; +$sel->type_ok("short_desc", $bug_summary); +$sel->type_ok("comment", "This is a test to check QA contact privs."); +$sel->check_ok('//input[@name="groups" and @value="Master"]'); +my $bug1_id = create_bug($sel, $bug_summary); + +# Create a saved search querying for all bugs with the powerless user +# as QA contact. + +open_advanced_search_page($sel); +$sel->remove_all_selections_ok("product"); +$sel->add_selection_ok("product", "TestProduct"); +$sel->remove_all_selections("bug_status"); +$sel->select_ok("f1", "label=QA Contact"); +$sel->select_ok("o1", "label=is equal to"); +$sel->type_ok("v1", $config->{unprivileged_user_login}, "Look for the powerless user as QA contact"); +$sel->click_ok("Search"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Bug List"); +$sel->is_element_present_ok("b$bug1_id", undef, "Bug $bug1_id is on the list"); +$sel->is_text_present_ok("Test for QA contact"); +$sel->type_ok("save_newqueryname", "My QA query"); +$sel->click_ok("remember"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Search created"); +my $text = trim($sel->get_text("message")); +ok($text =~ /OK, you have a new search named My QA query/, "New saved search 'My QA query'"); +$sel->click_ok("link=My QA query"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Bug List: My QA query"); +$sel->is_element_present_ok("b$bug1_id", undef, "Bug $bug1_id is on the list"); +$sel->is_text_present_ok("Test for QA contact"); + +# The saved search should still work, even with the QA contact field disabled. +# ("work" doesn't mean you should still see all bugs, depending on your role +# and privs!) + +set_parameters($sel, { "Bug Fields" => {"useqacontact-off" => undef} }); +$sel->click_ok("link=My QA query"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Bug List: My QA query"); +$sel->is_text_present_ok("One bug found"); +$sel->is_element_present_ok("b$bug1_id", undef, "Bug $bug1_id is on the list"); +$sel->click_ok("link=$bug1_id"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_like(qr/^$bug1_id /); +# The 'QA Contact' label must not be displayed. +ok(!$sel->is_text_present("QA Contact"), "The QA Contact label is not present"); +logout($sel); + +# You cannot access the bug when being logged out, as it's restricted +# to the Master group. + +$sel->type_ok("quicksearch_top", $bug1_id); +$sel->click_ok("find_top"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Bug Access Denied"); +$sel->is_text_present_ok("You are not authorized to access bug"); + +# You are still not allowed to access the bug when logged in as the +# powerless user, as the QA contact field is disabled. +# Don't use it log_in() as we want to follow this specific link. + +$sel->click_ok("link=log in to an account", undef, "Log in"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Log in to Bugzilla"); +$sel->is_text_present_ok("Bugzilla needs a legitimate login and password to continue"); +$sel->type_ok("Bugzilla_login", $config->{unprivileged_user_login}, "Enter login name"); +$sel->type_ok("Bugzilla_password", $config->{unprivileged_user_passwd}, "Enter password"); +$sel->click_ok("log_in", undef, "Submit credentials"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Bug Access Denied"); +$sel->is_text_present_ok("You are not authorized to access bug"); +logout($sel); + +# Re-enable the QA contact field. + +log_in($sel, $config, 'admin'); +set_parameters($sel, { "Bug Fields" => {"useqacontact-on" => undef} }); +logout($sel); + +# Log in as the powerless user. As the QA contact field is enabled again, +# you can now access the restricted bug. + +log_in($sel, $config, 'unprivileged'); +$sel->click_ok("link=Preferences"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("General Preferences"); +$sel->select_ok("state_addselfcc", "value=never"); +$sel->click_ok("update"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("General Preferences"); + +open_advanced_search_page($sel); +$sel->remove_all_selections_ok("product"); +$sel->add_selection_ok("product", "TestProduct"); +$sel->remove_all_selections_ok("bug_status"); +$sel->select_ok("f1", "label=QA Contact"); +$sel->select_ok("o1", "label=is equal to"); +$sel->type_ok("v1", $config->{unprivileged_user_login}, "Look for the powerless user as QA contact"); +$sel->click_ok("Search"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Bug List"); +$sel->is_text_present_ok("One bug found"); +$sel->is_element_present_ok("b$bug1_id", undef, "Bug $bug1_id is on the list"); +$sel->is_text_present_ok("Test for QA contact"); +$sel->click_ok("link=$bug1_id"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_like(qr/$bug1_id /); +$sel->click_ok("bz_qa_contact_edit_action"); +$sel->value_is("qa_contact", $config->{unprivileged_user_login}, "The powerless user is the current QA contact"); +$sel->check_ok("set_default_qa_contact"); +edit_bug($sel, $bug1_id, $bug_summary); + +# The user is no longer the QA contact, and he has no other role +# with the bug. He can no longer see it. + +$sel->is_text_present_ok("(list of e-mails not available)"); +$sel->click_ok("link=$bug1_id"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Bug Access Denied"); +logout($sel); + +$sel->stop(); diff --git a/xt/selenium/require_login.t b/xt/selenium/require_login.t new file mode 100644 index 000000000..d661121b5 --- /dev/null +++ b/xt/selenium/require_login.t @@ -0,0 +1,83 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# This Source Code Form is "Incompatible With Secondary Licenses", as +# defined by the Mozilla Public License, v. 2.0. + +use 5.10.1; +use strict; +use warnings; + +use FindBin qw($RealBin); +use lib "$RealBin/../lib"; + +use Test::More "no_plan"; + +use QA::Util; + +my ($sel, $config) = get_selenium(); + +# Turn on 'requirelogin'. + +log_in($sel, $config, 'admin'); +set_parameters($sel, { "User Authentication" => {"requirelogin-on" => undef} }); +logout($sel); + +# We try to access each page. None of the ones listed below should +# let you view it without being logged in. + +my @pages = qw(admin attachment buglist chart colchange describecomponents + describekeywords duplicates editclassifications editcomponents + editfields editflagtypes editgroups editkeywords editmilestones + editparams editproducts editsettings editusers editvalues + editversions editwhines editworkflow enter_bug page post_bug + process_bug query quips report reports request sanitycheck + search_plugin show_activity show_bug showdependencygraph + showdependencytree summarize_time userprefs votes); + +foreach my $page (@pages) { + $sel->open_ok("/$config->{bugzilla_installation}/${page}.cgi"); + if ($page ne 'votes' || $config->{test_extensions}) { + $sel->title_is("Log in to Bugzilla"); + } + else { + $sel->title_is("Extension Disabled"); + } +} + +# Those have parameters passed to the page, so we put them here separately. + +@pages = ("query.cgi?format=report-table", "query.cgi?format=report-graph", + "votes.cgi?action=show_user", "votes.cgi?action=show_bug"); + +foreach my $page (@pages) { + $sel->open_ok("/$config->{bugzilla_installation}/$page"); + if ($page !~ /^votes/ || $config->{test_extensions}) { + $sel->title_is("Log in to Bugzilla"); + } + else { + $sel->title_is("Extension Disabled"); + } +} + +# These pages should still be accessible. + +@pages = ("config.cgi", "createaccount.cgi", "index.cgi", "relogin.cgi", + "token.cgi?a=reqpw&loginname=" . $config->{unprivileged_user_login}); + +foreach my $page (@pages) { + $sel->open_ok("/$config->{bugzilla_installation}/$page"); + $sel->title_isnt("Log in to Bugzilla"); +} + +# Turn off 'requirelogin'. + +log_in($sel, $config, 'admin'); +set_parameters($sel, { "User Authentication" => {"requirelogin-off" => undef} }); +logout($sel); + +# Make sure we can access random pages again. +$sel->click_ok("link=Search"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_isnt("Log in to Bugzilla"); diff --git a/xt/selenium/sanity_check.t b/xt/selenium/sanity_check.t new file mode 100644 index 000000000..93b039d41 --- /dev/null +++ b/xt/selenium/sanity_check.t @@ -0,0 +1,49 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# This Source Code Form is "Incompatible With Secondary Licenses", as +# defined by the Mozilla Public License, v. 2.0. + +use 5.10.1; +use strict; +use warnings; + +use FindBin qw($RealBin); +use lib "$RealBin/../lib"; + +use Test::More "no_plan"; + +use QA::Util; + +my ($sel, $config) = get_selenium(); + +log_in($sel, $config, 'admin'); +go_to_admin($sel); +$sel->click_ok("link=Sanity Check", undef, "Go to Sanity Check (no parameter)"); +$sel->wait_for_page_to_load(WAIT_TIME); +$sel->title_is("Sanity Check", "Display sanitycheck.cgi"); +$sel->is_text_present_ok("Sanity check completed.", undef, "Page displayed correctly"); + +my @args = qw(rebuildvotecache createmissinggroupcontrolmapentries repair_creation_date + repair_bugs_fulltext remove_invalid_bug_references repair_bugs_fulltext + remove_invalid_attach_references remove_old_whine_targets rescanallBugMail); + +foreach my $arg (@args) { + $sel->open_ok("/$config->{bugzilla_installation}/sanitycheck.cgi?$arg=1"); + $sel->title_is("Suspicious Action", "Calling sanitycheck.cgi with no token triggers a confirmation page"); + $sel->click_ok("confirm", "Confirm the action"); + $sel->wait_for_page_to_load(WAIT_TIME); + $sel->title_is("Sanity Check", "Calling sanitycheck.cgi with $arg=1"); + if ($arg eq 'rescanallBugMail') { + # sanitycheck.cgi always stops after looking for unsent bugmail. So we cannot rely on + # "Sanity check completed." to determine if an error has been thrown or not. + $sel->is_text_present_ok("found with possibly unsent mail", undef, "Look for unsent bugmail"); + ok(!$sel->is_text_present("Software error"), "No error thrown"); + } + else { + $sel->is_text_present_ok("Sanity check completed.", undef, "Page displayed correctly"); + } +} + +logout($sel); diff --git a/xt/selenium/saved_searches.t b/xt/selenium/saved_searches.t new file mode 100644 index 000000000..a18b7fd49 --- /dev/null +++ b/xt/selenium/saved_searches.t @@ -0,0 +1,117 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# This Source Code Form is "Incompatible With Secondary Licenses", as +# defined by the Mozilla Public License, v. 2.0. + +use 5.10.1; +use strict; +use warnings; + +use FindBin qw($RealBin); +use lib "$RealBin/../lib"; + +use Test::More "no_plan"; + +use QA::Util; + +my ($sel, $config) = get_selenium(); + +# If a saved search named 'SavedSearchTEST1' exists, remove it. + +log_in($sel, $config, 'QA_Selenium_TEST'); +$sel->click_ok("link=Preferences"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("General Preferences"); +$sel->click_ok("link=Saved Searches"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Saved Searches"); + +if($sel->is_text_present("SavedSearchTEST1")) { + # There is no other way to identify this link (as they are all named "Forget"). + $sel->click_ok('//a[contains(@href,"buglist.cgi?cmdtype=dorem&remaction=forget&namedcmd=SavedSearchTEST1")]'); + $sel->wait_for_page_to_load_ok(WAIT_TIME); + $sel->title_is("Search is gone"); + $sel->is_text_present_ok("OK, the SavedSearchTEST1 search is gone."); +} + +# Create a new saved search. + +open_advanced_search_page($sel); +$sel->type_ok("short_desc", "test search"); +$sel->click_ok("Search"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Bug List"); +$sel->type_ok("save_newqueryname", "SavedSearchTEST1"); +$sel->click_ok("remember"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Search created"); +my $text = trim($sel->get_text("message")); +ok($text =~ /OK, you have a new search named SavedSearchTEST1./, "New search named SavedSearchTEST1 has been created"); +$sel->click_ok("link=SavedSearchTEST1"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Bug List: SavedSearchTEST1"); + +# Remove the saved search from the page footer. It should no longer be displayed there. + +$sel->click_ok("link=Preferences"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("General Preferences"); +$sel->click_ok("link=Saved Searches"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Saved Searches"); + +$sel->is_text_present_ok("SavedSearchTEST1"); +$sel->uncheck_ok('//input[@type="checkbox" and @alt="SavedSearchTEST1"]'); +# $sel->value_is("//input[\@type='checkbox' and \@alt='SavedSearchTEST1']", "off"); +$sel->click_ok("update"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Saved Searches"); +$text = trim($sel->get_text("message")); +ok($text =~ /The changes to your saved searches have been saved./, "Saved searches changes have been saved"); + +# Modify the saved search. Said otherwise, we should still be able to save +# a new search with exactly the same name. + +open_advanced_search_page($sel); +$sel->type_ok("short_desc", "bilboa"); +$sel->click_ok("Search"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Bug List"); +# As we said, this saved search should no longer be displayed in the page footer. +ok(!$sel->is_text_present("SavedSearchTEST1"), "SavedSearchTEST1 is not present in the page footer"); +$sel->type_ok("save_newqueryname", "SavedSearchTEST1"); +$sel->click_ok("remember"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Search updated"); +$text = trim($sel->get_text("message")); +ok($text =~ /Your search named SavedSearchTEST1 has been updated./, "Saved searche SavedSearchTEST1 has been updated."); + +# Make sure our new criteria has been saved (let's edit the saved search). +# As the saved search is no longer displayed in the footer, we have to go +# to the "Preferences" page to edit it. + +$sel->click_ok("link=Preferences"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("General Preferences"); +$sel->click_ok("link=Saved Searches"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Saved Searches"); + +$sel->is_text_present_ok("SavedSearchTEST1"); +$sel->click_ok('//a[@href="buglist.cgi?cmdtype=dorem&remaction=run&namedcmd=SavedSearchTEST1"]'); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Bug List: SavedSearchTEST1"); +$sel->click_ok("edit_search"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Search for bugs"); +$sel->value_is("short_desc", "bilboa"); +$sel->go_back_ok(); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->click_ok("forget_search"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Search is gone"); +$text = trim($sel->get_text("message")); +ok($text =~ /OK, the SavedSearchTEST1 search is gone./, "The SavedSearchTEST1 search is gone."); +logout($sel); diff --git a/xt/selenium/search.t b/xt/selenium/search.t new file mode 100644 index 000000000..c8fa9d770 --- /dev/null +++ b/xt/selenium/search.t @@ -0,0 +1,71 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# This Source Code Form is "Incompatible With Secondary Licenses", as +# defined by the Mozilla Public License, v. 2.0. + +use 5.10.1; +use strict; +use warnings; + +use FindBin qw($RealBin); +use lib "$RealBin/../lib"; + +use QA::Util; +use Test::More "no_plan"; + +my ($sel, $config) = get_selenium(); + +# TODO: This test really needs improvement. There is by far much more stuff +# to test in this area. + +# First, a very trivial search, which returns no result. + +go_to_home($sel, $config); +open_advanced_search_page($sel); +$sel->type_ok("short_desc", "ois£jdfm#sd%fasd!fm", "Type a non-existent string in the bug summary field"); +$sel->click_ok("Search"); +$sel->wait_for_page_to_load(WAIT_TIME); +$sel->title_is("Bug List"); +$sel->is_text_present_ok("Zarro Boogs found"); + +# Display all available columns. Look for all bugs assigned to a user who doesn't exist. + +$sel->open_ok("/$config->{bugzilla_installation}/buglist.cgi?quicksearch=%40xx45ft&columnlist=all"); +$sel->title_is("Bug List"); +$sel->is_text_present_ok("Zarro Boogs found"); + +# Now some real tests. + +log_in($sel, $config, 'canconfirm'); +file_bug_in_product($sel, "TestProduct"); +my $bug_summary = "Update this summary with this bug ID"; +$sel->type_ok("short_desc", $bug_summary); +$sel->type_ok("comment", "I'm supposed to appear in the coming buglist."); +my $bug1_id = create_bug($sel, $bug_summary); +$sel->click_ok("summary_edit_action"); +$bug_summary .= ": my ID is $bug1_id"; +$sel->type_ok("short_desc", $bug_summary); +$sel->type_ok("comment", "Updating bug summary...."); +edit_bug($sel, $bug1_id, $bug_summary); + +# Test pronoun substitution. + +open_advanced_search_page($sel); +$sel->remove_all_selections("bug_status"); +$sel->remove_all_selections("resolution"); +$sel->type_ok("short_desc", "my ID is $bug1_id"); +$sel->select_ok("f1", "label=Commenter"); +$sel->select_ok("o1", "label=is equal to"); +$sel->type_ok("v1", "%user%"); +$sel->click_ok("add_button"); +$sel->select_ok("f2", "label=Comment"); +$sel->select_ok("o2", "label=contains the string"); +$sel->type_ok("v2", "coming buglist"); +$sel->click_ok("Search"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Bug List"); +$sel->is_text_present_ok("One bug found"); +$sel->is_text_present_ok("Update this summary with this bug ID: my ID is $bug1_id"); +logout($sel); diff --git a/xt/selenium/security.t b/xt/selenium/security.t new file mode 100644 index 000000000..b89ea114e --- /dev/null +++ b/xt/selenium/security.t @@ -0,0 +1,198 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# This Source Code Form is "Incompatible With Secondary Licenses", as +# defined by the Mozilla Public License, v. 2.0. + +use 5.10.1; +use strict; +use warnings; + +use FindBin qw($RealBin); +use lib "$RealBin/../lib"; + +use Test::More "no_plan"; + +use QA::Util; + +my ($sel, $config) = get_selenium(CHROME_MODE); +my $urlbase = $config->{bugzilla_installation}; +my $admin_user = $config->{admin_user_login}; + +# Let's create a bug and attachment to play with. + +log_in($sel, $config, 'admin'); +file_bug_in_product($sel, "TestProduct"); +my $bug_summary = "Security checks"; +$sel->type_ok("short_desc", $bug_summary); +$sel->type_ok("comment", "This bug will be used to test security fixes."); +$sel->type_ok("data", $config->{attachment_file}); +$sel->type_ok("description", "simple patch, v1"); +$sel->click_ok("ispatch"); +my $bug1_id = create_bug($sel, $bug_summary); + + +####################################################################### +# Security bug 38862. +####################################################################### + +# No alternate host for attachments; cookies will be accessible. + +set_parameters($sel, { "Attachments" => {"allow_attachment_display-on" => undef, + "reset-attachment_base" => undef} }); + +go_to_bug($sel, $bug1_id); +$sel->click_ok("link=Add an attachment"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Create New Attachment for Bug #$bug1_id"); +$sel->type_ok("attach_text", "<html>\n<head>\n<title>I want your cookies</title>\n<head>\n" . + "<body>\n<script type='text/javascript'>document.write(document.cookie);</script>\n" . + "</body>\n</html>", "Writing text into the attachment textarea"); +$sel->type_ok("description", "show my cookies"); +edit_bug($sel, $bug1_id, $bug_summary, {id => "create"}); +my $alink = $sel->get_attribute('//a[@title="show my cookies"]@href'); +$alink =~ /id=(\d+)/; +my $attach1_id = $1; +$sel->click_ok("link=Attachment #$attach1_id"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_like(qr/Attachment $attach1_id Details for Bug $bug1_id/); +$sel->click_ok("link=edit details"); +$sel->type_ok("contenttypeentry", "text/html"); +edit_bug($sel, $bug1_id, $bug_summary, {id => "update"}); + +$sel->click_ok("link=show my cookies"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("I want your cookies"); +my @cookies = split(/[\s;]+/, $sel->get_body_text()); +my $nb_cookies = scalar @cookies; +ok($nb_cookies, "Found $nb_cookies cookies:\n" . join("\n", @cookies)); +ok(!$sel->is_cookie_present("Bugzilla_login"), "Bugzilla_login not accessible"); +ok(!$sel->is_cookie_present("Bugzilla_logincookie"), "Bugzilla_logincookie not accessible"); +$sel->go_back_ok(); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_like(qr/^$bug1_id /); + +# Alternate host for attachments; no cookie should be accessible. + +set_parameters($sel, { "Attachments" => {"attachment_base" => {type => "text", + value => "http://127.0.0.1/$urlbase"}} }); +go_to_bug($sel, $bug1_id); +$sel->click_ok("link=show my cookies"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("I want your cookies"); +@cookies = split(/[\s;]+/, $sel->get_body_text()); +$nb_cookies = scalar @cookies; +ok(!$nb_cookies, "No cookies found"); +ok(!$sel->is_cookie_present("Bugzilla_login"), "Bugzilla_login not accessible"); +ok(!$sel->is_cookie_present("Bugzilla_logincookie"), "Bugzilla_logincookie not accessible"); +$sel->go_back_ok(); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_like(qr/^$bug1_id /); + +set_parameters($sel, { "Attachments" => {"reset-attachment_base" => undef} }); + +####################################################################### +# Security bug 472362. +####################################################################### + +$sel->click_ok("link=Preferences"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("General Preferences"); +my $admin_cookie = $sel->get_value("token"); +logout($sel); + +log_in($sel, $config, 'editbugs'); +$sel->click_ok("link=Preferences"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("General Preferences"); +my $editbugs_cookie = $sel->get_value("token"); + +# Using our own unused token is fine. + +$sel->open_ok("/$urlbase/userprefs.cgi?dosave=1&display_quips=off&token=$editbugs_cookie"); +$sel->title_is("General Preferences"); +$sel->is_text_present_ok("The changes to your general preferences have been saved"); + +# Reusing a token must fail. They must all trigger the Suspicious Action warning. + +my @args = ("", "token=", "token=i123x", "token=$admin_cookie", "token=$editbugs_cookie"); + +foreach my $arg (@args) { + $sel->open_ok("/$urlbase/userprefs.cgi?dosave=1&display_quips=off&$arg"); + $sel->title_is("Suspicious Action"); + + if ($arg eq "token=$admin_cookie") { + $sel->is_text_present_ok("Generated by: admin <$admin_user>"); + $sel->is_text_present_ok("This token has not been generated by you"); + } + else { + $sel->is_text_present_ok("It looks like you didn't come from the right page"); + } +} +logout($sel); + +####################################################################### +# Security bug 529416. +####################################################################### + +log_in($sel, $config, 'admin'); +file_bug_in_product($sel, "TestProduct"); +$sel->type_ok("alias", "secret_qa_bug_" . ($bug1_id + 1)); +my $bug_summary2 = "Private QA Bug"; +$sel->type_ok("short_desc", $bug_summary2); +$sel->type_ok("comment", "This private bug is used to test security fixes."); +$sel->type_ok("dependson", $bug1_id); +$sel->check_ok('//input[@name="groups" and @value="Master"]'); +my $bug2_id = create_bug($sel, $bug_summary2); + +go_to_bug($sel, $bug1_id); +$sel->is_text_present_ok("secret_qa_bug_$bug2_id"); +logout($sel); + +log_in($sel, $config, 'editbugs'); +go_to_bug($sel, $bug1_id); +ok(!$sel->is_text_present("secret_qa_bug_$bug2_id"), "The alias 'secret_qa_bug_$bug2_id' is not visible for unauthorized users"); +$sel->is_text_present_ok($bug2_id); +logout($sel); + +go_to_bug($sel, $bug1_id); +ok(!$sel->is_text_present("secret_qa_bug_$bug2_id"), "The alias 'secret_qa_bug_$bug2_id' is not visible for logged out users"); +$sel->is_text_present_ok($bug2_id); + +####################################################################### +# Security bug 472206. +# Keep this test as the very last one as the File Saver will remain +# open till the end of the script. Selenium is currently* unable +# to interact with it and close it (* = 2.6.0). +####################################################################### + +log_in($sel, $config, 'admin'); +set_parameters($sel, { "Attachments" => {"allow_attachment_display-off" => undef} }); + +# Attachments are not viewable. + +go_to_bug($sel, $bug1_id); +$sel->click_ok("link=Details"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_like(qr/Attachment \d+ Details for Bug $bug1_id/); +$sel->is_text_present_ok("The attachment is not viewable in your browser due to security restrictions"); +$sel->click_ok("link=View"); +# Wait 1 second to give the browser a chance to display the attachment. +# Do not use wait_for_page_to_load_ok() as the File Saver will never go away. +sleep(1); +ok(!$sel->is_text_present('@@'), "Patch not displayed"); + +# Enable viewing attachments. + +set_parameters($sel, { "Attachments" => {"allow_attachment_display-on" => undef} }); + +go_to_bug($sel, $bug1_id); +$sel->click_ok('link=simple patch, v1'); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is(""); +$sel->is_text_present_ok('@@'); +$sel->go_back_ok(); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_like(qr/$bug1_id /); +logout($sel); diff --git a/xt/selenium/shared_searches.t b/xt/selenium/shared_searches.t new file mode 100644 index 000000000..f9443fa98 --- /dev/null +++ b/xt/selenium/shared_searches.t @@ -0,0 +1,199 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# This Source Code Form is "Incompatible With Secondary Licenses", as +# defined by the Mozilla Public License, v. 2.0. + +use 5.10.1; +use strict; +use warnings; + +use FindBin qw($RealBin); +use lib "$RealBin/../lib"; + +use Test::More "no_plan"; + +use QA::Util; + +my ($sel, $config) = get_selenium(); + +# Set the querysharegroup param to be the canconfirm group. + +log_in($sel, $config, 'admin'); +set_parameters($sel, { "Group Security" => {"querysharegroup" => {type => "select", value => "canconfirm"}} }); + +# Create new saved search and call it 'Shared Selenium buglist'. + +$sel->type_ok("quicksearch_top", ":TestProduct Selenium"); +$sel->click_ok("find_top"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Bug List"); +$sel->type_ok("save_newqueryname", "Shared Selenium buglist"); +$sel->click_ok("remember"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Search created"); +my $text = trim($sel->get_text("message")); +ok($text =~ /OK, you have a new search named Shared Selenium buglist./, "New search named 'Shared Selenium buglist' has been created"); + +# Retrieve the newly created saved search's internal ID and make sure it's displayed +# in the footer by default. + +$sel->click_ok("link=Preferences"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("General Preferences"); +$sel->click_ok("link=Saved Searches"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Saved Searches"); +my $ssname = $sel->get_attribute('//input[@type="checkbox" and @alt="Shared Selenium buglist"]@name'); +$ssname =~ /(?:link_in_footer_(\d+))/; +my $saved_search1_id = $1; +$sel->is_checked_ok("link_in_footer_$saved_search1_id"); + +# As an admin, the "Add to footer" checkbox must be displayed, but unchecked by default. + +$sel->select_ok("share_$saved_search1_id", "label=canconfirm"); +ok(!$sel->is_checked("force_$saved_search1_id"), "Shared search not displayed in other users' footer by default"); +$sel->click_ok("force_$saved_search1_id"); +$sel->click_ok("update"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Saved Searches"); +logout($sel); + +# Log in as the "canconfirm" user. The search shared by the admin must appear +# in the footer. + +log_in($sel, $config, 'canconfirm'); +$sel->is_text_present_ok("Shared Selenium buglist"); +$sel->click_ok("link=Shared Selenium buglist"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Bug List: Shared Selenium buglist"); +# You cannot delete other users' saved searches. +ok(!$sel->is_element_present("forget_search"), "'Forget...' button not available"); + +# The name of the sharer must appear in the "Saved Searches" section. + +$sel->click_ok("link=Preferences"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("General Preferences"); +$sel->click_ok("link=Saved Searches"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Saved Searches"); +$sel->is_text_present_ok($config->{admin_user_login}); + +# Remove the shared search from your footer. + +$sel->is_checked_ok("link_in_footer_$saved_search1_id"); +$sel->click_ok("link_in_footer_$saved_search1_id"); +$sel->click_ok("update"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Saved Searches"); +# Go to a page where the query name is unlikely to appear in the main page. +$sel->click_ok("link=Permissions"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Permissions"); +ok(!$sel->is_text_present("Shared Selenium buglist"), "Shared query no longer displayed in the footer"); + +# Create your own saved search, and share it with the canconfirm group. + +$sel->type_ok("quicksearch_top", ":TestProduct sw:helpwanted"); +$sel->click_ok("find_top"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Bug List"); +$sel->type_ok("save_newqueryname", "helpwanted"); +$sel->click_ok("remember"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Search created"); +$text = trim($sel->get_text("message")); +ok($text =~ /OK, you have a new search named helpwanted./, "New search named helpwanted has been created"); + +$sel->click_ok("link=Preferences"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("General Preferences"); +$sel->click_ok("link=Saved Searches"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Saved Searches"); +$ssname = $sel->get_attribute('//input[@type="checkbox" and @alt="helpwanted"]@name'); +$ssname =~ /(?:link_in_footer_(\d+))/; +my $saved_search2_id = $1; +# Our own saved searches are displayed in the footer by default. +$sel->is_checked_ok("link_in_footer_$saved_search2_id"); +$sel->select_ok("share_$saved_search2_id", "label=canconfirm"); +$sel->click_ok("update"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Saved Searches"); +logout($sel); + +# Log in as admin again. The other user is not a blesser for the 'canconfirm' +# group, and so his shared search must not be displayed by default. But it +# must still be available and can be added to the footer, if desired. + +log_in($sel, $config, 'admin'); +ok(!$sel->is_text_present("helpwanted"), "No 'helpwanted' shared search displayed"); +$sel->click_ok("link=Preferences"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("General Preferences"); +$sel->click_ok("link=Saved Searches"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Saved Searches"); +$sel->is_text_present_ok("helpwanted"); +$sel->is_text_present_ok($config->{canconfirm_user_login}); + +ok(!$sel->is_checked("link_in_footer_$saved_search2_id"), "Shared query available but not displayed"); +$sel->click_ok("link_in_footer_$saved_search2_id"); +$sel->click_ok("update"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Saved Searches"); +# This query is now available from the footer. +$sel->click_ok("link=helpwanted"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Bug List: helpwanted"); + +# Remove the 'Shared Selenium buglist' query. + +$sel->click_ok("link=Preferences"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("General Preferences"); +$sel->click_ok("link=Saved Searches"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Saved Searches"); +# There is no better way to identify the link +$sel->click_ok('//a[contains(@href,"buglist.cgi?cmdtype=dorem&remaction=forget&namedcmd=Shared%20Selenium%20buglist")]', + undef, "Deleting the 'Shared Selenium buglist' search"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Search is gone"); +$text = trim($sel->get_text("message")); +ok($text =~ /OK, the Shared Selenium buglist search is gone./, "The 'Shared Selenium buglist' search is gone"); +logout($sel); + +# Make sure that the 'helpwanted' query is not shared with the QA_Selenium_TEST +# user as he doesn't belong to the 'canconfirm' group. + +log_in($sel, $config, 'QA_Selenium_TEST'); +ok(!$sel->is_text_present("helpwanted"), "The 'helpwanted' query is not displayed in the footer"); +$sel->click_ok("link=Preferences"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("General Preferences"); +$sel->click_ok("link=Saved Searches"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Saved Searches"); +ok(!$sel->is_text_present("helpwanted"), "The 'helpwanted' query is not shared with this user"); +logout($sel); + +# Now remove the 'helpwanted' saved search. + +log_in($sel, $config, 'canconfirm'); +$sel->click_ok("link=Preferences"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("General Preferences"); +$sel->click_ok("link=Saved Searches"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Saved Searches"); +ok(!$sel->is_text_present("Shared Selenium buglist"), "The 'Shared Selenium buglist' is no longer available"); +$sel->click_ok('//a[contains(@href,"buglist.cgi?cmdtype=dorem&remaction=forget&namedcmd=helpwanted")]', + undef, "Deleting the 'helpwanted' search"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Search is gone"); +$text = trim($sel->get_text("message")); +ok($text =~ /OK, the helpwanted search is gone./, "The 'helpwanted' search is gone"); +logout($sel); diff --git a/xt/selenium/show_all_products.t b/xt/selenium/show_all_products.t new file mode 100644 index 000000000..894554665 --- /dev/null +++ b/xt/selenium/show_all_products.t @@ -0,0 +1,56 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# This Source Code Form is "Incompatible With Secondary Licenses", as +# defined by the Mozilla Public License, v. 2.0. + +use 5.10.1; +use strict; +use warnings; + +use FindBin qw($RealBin); +use lib "$RealBin/../lib"; + +use Test::More "no_plan"; + +use QA::Util; + +my ($sel, $config) = get_selenium(); + +log_in($sel, $config, 'admin'); +set_parameters($sel, { "Bug Fields" => {"useclassification-on" => undef} }); + +# Do not use file_bug_in_product() because our goal here is not to file +# a bug but to check what is present in the UI, and also to make sure +# that we get exactly the right page with the right information. +# +# The admin is not a member of the "QA‑Selenium‑TEST" group, and so +# cannot see the "QA‑Selenium‑TEST" product. + +$sel->click_ok("link=New"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->is_text_present_ok("Select Classification"); +my $full_text = trim($sel->get_body_text()); +ok($full_text =~ /All: Show all products/, "The 'All' link is displayed"); +$sel->click_ok("link=All"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->is_text_present_ok("Select Product"); +ok(!$sel->is_text_present("QA-Selenium-TEST"), "The QA-Selenium-TEST product is not displayed"); +logout($sel); + +# Same steps, but for a member of the "QA‑Selenium‑TEST" group. +# The "QA‑Selenium‑TEST" product must be visible to him. + +log_in($sel, $config, 'QA_Selenium_TEST'); +$sel->click_ok("link=New"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->is_text_present_ok("Select Classification"); +$sel->click_ok("link=All"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->is_text_present_ok("Select Product"); +$sel->is_text_present_ok("QA-Selenium-TEST"); +$sel->click_ok('//a[contains(@href, "product=QA-Selenium-TEST")]'); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Enter Bug: QA-Selenium-TEST"); +logout($sel); diff --git a/xt/selenium/shutdown.t b/xt/selenium/shutdown.t new file mode 100644 index 000000000..8751cd614 --- /dev/null +++ b/xt/selenium/shutdown.t @@ -0,0 +1,77 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# This Source Code Form is "Incompatible With Secondary Licenses", as +# defined by the Mozilla Public License, v. 2.0. + +use 5.10.1; +use strict; +use warnings; + +use FindBin qw($RealBin); +use lib "$RealBin/../lib"; + +use Test::More "no_plan"; + +use QA::Util; + +my ($sel, $config) = get_selenium(); + +log_in($sel, $config, 'admin'); +set_parameters($sel, { "General" => {shutdownhtml => {type => "text", + value => "I'm down (set by test_shutdown.t)" } + } }); + +# None of the following pages should be accessible when Bugzilla is down. + +my @pages = qw(admin attachment buglist chart colchange config createaccount + describecomponents describekeywords duplicates + editclassifications editcomponents editfields editflagtypes + editgroups editkeywords editmilestones editproducts editsettings + editusers editvalues editversions editwhines editworkflow + enter_bug index page post_bug process_bug query quips relogin + report reports request sanitycheck search_plugin show_activity + show_bug showdependencygraph showdependencytree summarize_time + token userprefs votes xmlrpc); + +foreach my $page (@pages) { + $sel->open_ok("/$config->{bugzilla_installation}/${page}.cgi"); + $sel->title_is("Bugzilla is Down"); +} + +# Those have parameters passed to the page, so we put them here separately. + +@pages = ("query.cgi?format=report-table", "query.cgi?format=report-graph", + "votes.cgi?action=show_user", "votes.cgi?action=show_bug"); + +foreach my $page (@pages) { + $sel->open_ok("/$config->{bugzilla_installation}/$page"); + $sel->title_is("Bugzilla is Down"); +} + +# Clear 'shutdownhtml', to re-enable Bugzilla. +# At this point, the admin has been logged out. We cannot use log_in(), +# nor set_parameters(), due to shutdownhtml being active. + +$sel->open_ok("/$config->{bugzilla_installation}/editparams.cgi"); +$sel->title_is("Log in to Bugzilla"); +$sel->type_ok("Bugzilla_login", $config->{admin_user_login}, "Enter admin login name"); +$sel->type_ok("Bugzilla_password", $config->{admin_user_passwd}, "Enter admin password"); +$sel->click_ok("log_in"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Configuration: Required Settings"); +$sel->click_ok("link=General"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Configuration: General"); +$sel->type_ok("shutdownhtml", ""); +$sel->click_ok('//input[@type="submit" and @value="Save Changes"]', undef, "Save Changes"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Parameters Updated"); + +# Accessing index.cgi should work again now. + +$sel->click_ok("link=Home"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Bugzilla Main Page"); +logout($sel); diff --git a/xt/selenium/status_whiteboard.t b/xt/selenium/status_whiteboard.t new file mode 100644 index 000000000..3ddda7b86 --- /dev/null +++ b/xt/selenium/status_whiteboard.t @@ -0,0 +1,118 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# This Source Code Form is "Incompatible With Secondary Licenses", as +# defined by the Mozilla Public License, v. 2.0. + +use 5.10.1; +use strict; +use warnings; + +use FindBin qw($RealBin); +use lib "$RealBin/../lib"; + +use Test::More "no_plan"; + +use QA::Util; + +my ($sel, $config) = get_selenium(); + +log_in($sel, $config, 'admin'); +set_parameters($sel, {'Bug Fields' => {'usestatuswhiteboard-on' => undef}}); + +# Make sure the status whiteboard is displayed and add stuff to it. + +file_bug_in_product($sel, "TestProduct"); +$sel->select_ok("component", "TestComponent"); +my $bug_summary = "white and black"; +$sel->type_ok("short_desc", $bug_summary); +$sel->type_ok("comment", "This bug is to test the status whiteboard"); +my $bug1_id = create_bug($sel, $bug_summary); +$sel->is_text_present_ok("Whiteboard:"); +$sel->type_ok("status_whiteboard", "[msg from test_status_whiteboard.t: x77v]"); +edit_bug($sel, $bug1_id, $bug_summary); + +file_bug_in_product($sel, "TestProduct"); +$sel->select_ok("component", "TestComponent"); +my $bug_summary2 = "WTC"; +$sel->type_ok("short_desc", $bug_summary2); +$sel->type_ok("comment", "bugzillation!"); +my $bug2_id = create_bug($sel, $bug_summary2); +$sel->type_ok("status_whiteboard", "[msg from test_status_whiteboard.t: x77v]"); +edit_bug($sel, $bug2_id, $bug_summary2); + +# Now search these bugs above using data being in the status whiteboard, +# and save the query. + +open_advanced_search_page($sel); +$sel->remove_all_selections_ok("product"); +$sel->remove_all_selections_ok("bug_status"); +$sel->type_ok("status_whiteboard", "x77v"); +$sel->click_ok("Search"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Bug List"); +$sel->is_text_present_ok("2 bugs found"); +$sel->type_ok("save_newqueryname", "sw-x77v"); +$sel->click_ok("remember"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Search created"); +my $text = trim($sel->get_text("message")); +ok($text =~ /you have a new search named sw-x77v/, 'Saved search correctly saved'); + +# Make sure the saved query works. + +$sel->click_ok("link=sw-x77v"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Bug List: sw-x77v"); +$sel->is_text_present_ok("2 bugs found"); + +# The status whiteboard should no longer be displayed in both the query +# and bug view pages (query.cgi and show_bug.cgi) when usestatuswhiteboard +# is off. + +set_parameters($sel, {'Bug Fields' => {'usestatuswhiteboard-off' => undef}}); +$sel->click_ok("link=Search"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Search for bugs"); +ok(!$sel->is_text_present("Whiteboard:"), "Whiteboard label no longer displayed in the search page"); +go_to_bug($sel, $bug1_id); +ok(!$sel->is_text_present("Whiteboard:"), "Whiteboard label no longer displayed in the bug page"); + +# Queries based on the status whiteboard should still work when +# the parameter is off. + +$sel->click_ok("link=sw-x77v"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Bug List: sw-x77v"); +$sel->is_text_present_ok("2 bugs found"); + +# Turn on usestatuswhiteboard again as some other scripts may expect the status +# whiteboard to be available by default. + +set_parameters($sel, {'Bug Fields' => {'usestatuswhiteboard-on' => undef}}); + +# Clear the status whiteboard and delete the saved search. + +$sel->click_ok("link=sw-x77v"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Bug List: sw-x77v"); +$sel->is_text_present_ok("2 bugs found"); +$sel->click_ok("mass_change"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Bug List"); +$sel->click_ok("check_all"); +$sel->type_ok("status_whiteboard", ""); +$sel->click_ok("commit"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Bugs processed"); + +$sel->click_ok("link=sw-x77v"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Bug List: sw-x77v"); +$sel->is_text_present_ok("Zarro Boogs found"); +$sel->click_ok("forget_search"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Search is gone"); +$sel->is_text_present_ok("OK, the sw-x77v search is gone."); +logout($sel); diff --git a/xt/selenium/strict_isolation.t b/xt/selenium/strict_isolation.t new file mode 100644 index 000000000..ecd72b207 --- /dev/null +++ b/xt/selenium/strict_isolation.t @@ -0,0 +1,145 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# This Source Code Form is "Incompatible With Secondary Licenses", as +# defined by the Mozilla Public License, v. 2.0. + +use 5.10.1; +use strict; +use warnings; + +use FindBin qw($RealBin); +use lib "$RealBin/../lib"; + +use Test::More "no_plan"; + +use QA::Util; + +my ($sel, $config) = get_selenium(); +my $qa_user = $config->{QA_Selenium_TEST_user_login}; +my $no_privs_user = $config->{unprivileged_user_login}; + +log_in($sel, $config, 'admin'); +set_parameters($sel, { "Group Security" => {"strict_isolation-on" => undef} }); + +# Restrict the bug to the "Master" group, so that we can check that only +# allowed people can be CC'ed to the bug. + +file_bug_in_product($sel, 'Another Product'); +$sel->select_ok("component", "label=c2"); +$sel->select_ok("version", "label=Another2"); +my $bug_summary = "Test isolation"; +$sel->type_ok("short_desc", $bug_summary); +$sel->type_ok("comment", "Unallowed users refused"); +my $master_gid = $sel->get_attribute('//input[@type="checkbox" and @name="groups" and @value="Master"]@id'); +$sel->check_ok($master_gid); +$master_gid =~ s/group_//; +my $bug1_id = create_bug($sel, $bug_summary); + +# At that point, CANEDIT is off and so everybody can be CC'ed to the bug. + +$sel->click_ok("cc_edit_area_showhide"); +$sel->type_ok("newcc", "$qa_user, $no_privs_user"); +edit_bug_and_return($sel, $bug1_id, $bug_summary); + +$sel->click_ok("cc_edit_area_showhide"); +$sel->add_selection_ok("cc", "label=$no_privs_user"); +$sel->add_selection_ok("cc", "label=$qa_user"); +$sel->check_ok("removecc"); +edit_bug($sel, $bug1_id, $bug_summary); + +# Now enable CANEDIT for the "Master" group. This will enable strict isolation +# for the product. + +edit_product($sel, "Another Product"); +$sel->click_ok("link=Edit Group Access Controls:"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Edit Group Controls for Another Product"); +$sel->check_ok("canedit_$master_gid"); +$sel->click_ok("submit"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Update group access controls for Another Product"); + +# Non-members can no longer be CC'ed to the bug. + +go_to_bug($sel, $bug1_id); +$sel->click_ok("cc_edit_area_showhide"); +$sel->type_ok("newcc", $no_privs_user); +$sel->click_ok("commit"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Invalid User Group"); +$sel->is_text_present_ok("User '$no_privs_user' is not able to edit the 'Another Product' Product"); +$sel->go_back_ok(); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_like(qr/^$bug1_id /); +$sel->click_ok("cc_edit_area_showhide"); +$sel->type_ok("newcc", $qa_user); +$sel->click_ok("commit"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Invalid User Group"); +$sel->is_text_present_ok("User '$qa_user' is not able to edit the 'Another Product' Product"); + +# Now set QA_Selenium_TEST user as a member of the Master group. + +go_to_admin($sel); +$sel->click_ok("link=Users"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Search users"); +$sel->type_ok("matchstr", $qa_user); +$sel->select_ok("matchtype", "label=exact (find this user)"); +$sel->click_ok("search"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Edit user QA-Selenium-TEST <$qa_user>"); +$sel->check_ok("group_$master_gid"); +$sel->click_ok("update"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("User $qa_user updated"); + +# The QA_Selenium_TEST user can now be CC'ed to the bug. + +go_to_bug($sel, $bug1_id); +$sel->click_ok("cc_edit_area_showhide"); +$sel->type_ok("newcc", $qa_user); +edit_bug_and_return($sel, $bug1_id, $bug_summary); +$sel->click_ok("cc_edit_area_showhide"); +$sel->add_selection_ok("cc", "label=$qa_user"); +$sel->check_ok("removecc"); +edit_bug_and_return($sel, $bug1_id, $bug_summary); + +# The powerless user still cannot be CC'ed. + +$sel->click_ok("cc_edit_area_showhide"); +$sel->type_ok("newcc", "$qa_user, $no_privs_user"); +$sel->click_ok("commit"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Invalid User Group"); +$sel->is_text_present_ok("User '$no_privs_user' is not able to edit the 'Another Product' Product"); + +# Reset parameters back to defaults. + +set_parameters($sel, { "Group Security" => {"strict_isolation-off" => undef} }); + +go_to_admin($sel); +$sel->click_ok("link=Users"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Search users"); +$sel->type_ok("matchstr", $qa_user); +$sel->select_ok("matchtype", "label=exact (find this user)"); +$sel->click_ok("search"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Edit user QA-Selenium-TEST <$qa_user>"); +$sel->uncheck_ok("group_$master_gid"); +$sel->click_ok("update"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("User $qa_user updated"); + +edit_product($sel, "Another Product"); +$sel->click_ok("link=Edit Group Access Controls:"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Edit Group Controls for Another Product"); +$sel->uncheck_ok("canedit_$master_gid"); +$sel->click_ok("submit"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Update group access controls for Another Product"); +logout($sel); diff --git a/xt/selenium/sudo_sessions.t b/xt/selenium/sudo_sessions.t new file mode 100644 index 000000000..5a1b7c98b --- /dev/null +++ b/xt/selenium/sudo_sessions.t @@ -0,0 +1,158 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# This Source Code Form is "Incompatible With Secondary Licenses", as +# defined by the Mozilla Public License, v. 2.0. + +use 5.10.1; +use strict; +use warnings; + +use FindBin qw($RealBin); +use lib "$RealBin/../lib"; + +use Test::More "no_plan"; + +use QA::Util; + +my ($sel, $config) = get_selenium(); + +# Turn on the usevisibilitygroups param so that some users are invisible. + +log_in($sel, $config, 'admin'); +set_parameters($sel, { "Group Security" => {"usevisibilitygroups-on" => undef} }); + +# You can see all users from editusers.cgi, but once you leave this page, +# usual group visibility restrictions apply and the "powerless" user cannot +# be sudo'ed as he is in no group. + +go_to_admin($sel); +$sel->click_ok("link=Users"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Search users"); +$sel->type_ok("matchstr", $config->{unprivileged_user_login}); +$sel->select_ok("matchtype", "label=exact (find this user)"); +$sel->click_ok("search"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Edit user no-privs <$config->{unprivileged_user_login}>"); +$sel->value_is("login", $config->{unprivileged_user_login}); +$sel->click_ok("link=Impersonate this user"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Begin sudo session"); +$sel->value_is("target_login", $config->{unprivileged_user_login}); +$sel->type_ok("reason", "Selenium test about sudo sessions"); +$sel->type_ok("password", $config->{admin_user_passwd}, "Enter admin password"); +$sel->click_ok('//input[@value="Begin Session"]'); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Match Failed"); +my $error_msg = trim($sel->get_text("error_msg")); +ok($error_msg eq "$config->{unprivileged_user_login} does not exist or you are not allowed to see that user.", + "Cannot impersonate users you cannot see"); + +# Turn off the usevisibilitygroups param so that all users are visible again. + +set_parameters($sel, { "Group Security" => {"usevisibilitygroups-off" => undef} }); + +# The "powerless" user can now be sudo'ed. + +go_to_admin($sel); +$sel->click_ok("link=Users"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Search users"); +$sel->type_ok("matchstr", $config->{unprivileged_user_login}); +$sel->select_ok("matchtype", "label=exact (find this user)"); +$sel->click_ok("search"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Edit user no-privs <$config->{unprivileged_user_login}>"); +$sel->value_is("login", $config->{unprivileged_user_login}); +$sel->click_ok("link=Impersonate this user"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Begin sudo session"); +$sel->value_is("target_login", $config->{unprivileged_user_login}); +$sel->type_ok("password", $config->{admin_user_passwd}, "Enter admin password"); +$sel->click_ok('//input[@value="Begin Session"]'); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Sudo session started"); +my $text = trim($sel->get_text("message")); +ok($text =~ /The sudo session has been started/, "The sudo session has been started"); + +# Make sure this user is not an admin and has no privs at all, and that +# he cannot access editusers.cgi (despite the sudoer can). + +$sel->click_ok("link=Preferences"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("General Preferences"); +$sel->click_ok("link=Permissions"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Permissions"); +$sel->is_text_present_ok("There are no permission bits set on your account"); +# We access the page directly as there is no link pointing to it. +$sel->open_ok("/$config->{bugzilla_installation}/editusers.cgi"); +$sel->title_is("Authorization Required"); +$error_msg = trim($sel->get_text("error_msg")); +ok($error_msg =~ /^Sorry, you aren't a member of the 'editusers' group/, "Not a member of the editusers group"); +$sel->click_ok("link=end session"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Sudo session complete"); +$sel->is_text_present_ok("Your sudo session has ended"); + +# Try to access the sudo page directly, with no credentials. + +$sel->open_ok("/$config->{bugzilla_installation}/relogin.cgi?action=begin-sudo&target_login=$config->{admin_user_login}"); +$sel->title_is("Password Required"); + +# Now try to start a sudo session directly, with all required credentials. + +$sel->open_ok("/$config->{bugzilla_installation}/relogin.cgi?action=begin-sudo&password=$config->{admin_user_passwd}&target_login=$config->{unprivileged_user_login}", undef, "Impersonate a user directly by providing all required data"); +# A direct access to the page is supposed to have no Referer header set, +# which would trigger the "Untrusted Authentication Request" error, but +# due to the way Selenium works, the Referer header is set and the +# "Preparation Required" error is thrown instead. In any case, one of +# those two errors must be thrown. +my $title = $sel->get_title(); +ok($title eq "Untrusted Authentication Request" || $title eq "Preparation Required", $title); + +# Now try to sudo an admin, which is not allowed. + +$sel->open_ok("/$config->{bugzilla_installation}/relogin.cgi?action=prepare-sudo&target_login=$config->{admin_user_login}"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Begin sudo session"); +$sel->value_is("target_login", $config->{admin_user_login}); +$sel->type_ok("reason", "Selenium hack"); +$sel->type_ok("password", $config->{admin_user_passwd}, "Enter admin password"); +$sel->click_ok('//input[@value="Begin Session"]'); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("User Protected"); +$error_msg = trim($sel->get_text("error_msg")); +ok($error_msg =~ /^The user $config->{admin_user_login} may not be impersonated by sudoers/, "Cannot impersonate administrators"); + +# Now try to sudo a non-existing user account, with no password. + +$sel->go_back_ok(); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Begin sudo session"); +# Starting with 5.0, the password field is a type=password and is marked +# "required". This means that we need to remove the required attribute from +# the input so that it can still be checked by the backend code. +my $script = q{ + document.getElementById('password').removeAttribute('required'); +}; +$sel->run_script($script); +$sel->type_ok("target_login", 'foo@bar.com'); +$sel->click_ok('//input[@value="Begin Session"]'); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Password Required"); + +# Same as above, but with your password. + +$sel->open_ok("/$config->{bugzilla_installation}/relogin.cgi?action=prepare-sudo&target_login=foo\@bar.com"); +$sel->title_is("Begin sudo session"); +$sel->value_is("target_login", 'foo@bar.com'); +$sel->type_ok("password", $config->{admin_user_passwd}, "Enter admin password"); +$sel->click_ok('//input[@value="Begin Session"]'); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Match Failed"); +$error_msg = trim($sel->get_text("error_msg")); +ok($error_msg eq 'foo@bar.com does not exist or you are not allowed to see that user.', "Cannot impersonate non-existing accounts"); +logout($sel); diff --git a/xt/selenium/target_milestones.t b/xt/selenium/target_milestones.t new file mode 100644 index 000000000..6c5cf637f --- /dev/null +++ b/xt/selenium/target_milestones.t @@ -0,0 +1,111 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# This Source Code Form is "Incompatible With Secondary Licenses", as +# defined by the Mozilla Public License, v. 2.0. + +use 5.10.1; +use strict; +use warnings; + +use FindBin qw($RealBin); +use lib "$RealBin/../lib"; + +use Test::More "no_plan"; + +use QA::Util; + +my ($sel, $config) = get_selenium(); + +log_in($sel, $config, 'admin'); +set_parameters($sel, { "Bug Fields" => {"usetargetmilestone-on" => undef} }); + +# Create a new milestone to the 'TestProduct' product. + +edit_product($sel, "TestProduct"); +$sel->click_ok("link=Edit milestones:"); +$sel->wait_for_page_to_load(WAIT_TIME); +$sel->title_is("Select milestone of product 'TestProduct'"); +$sel->click_ok("link=Add"); +$sel->wait_for_page_to_load(WAIT_TIME); +$sel->title_is("Add Milestone to Product 'TestProduct'"); +$sel->type_ok("milestone", "TM1"); +$sel->type_ok("sortkey", "10"); +$sel->click_ok("create"); +$sel->wait_for_page_to_load(WAIT_TIME); +$sel->title_is("Milestone Created"); + +# Edit the milestone of bugs. + +file_bug_in_product($sel, "TestProduct"); +$sel->select_ok("component", "TestComponent"); +my $bug_summary = "stone and rock"; +$sel->type_ok("short_desc", $bug_summary); +$sel->type_ok("comment", "This bug is to test milestones"); +my $bug1_id = create_bug($sel, $bug_summary); +$sel->is_text_present_ok("Target Milestone:"); +$sel->select_ok("target_milestone", "label=TM1"); +edit_bug($sel, $bug1_id, $bug_summary); + +# Query for bugs with the TM1 milestone. + +open_advanced_search_page($sel); +$sel->is_text_present_ok("Target Milestone:"); +$sel->remove_all_selections_ok("product"); +$sel->add_selection_ok("product", "label=TestProduct"); +$sel->add_selection_ok("target_milestone", "label=TM1"); +$sel->click_ok("Search"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Bug List"); +$sel->is_text_present_ok("One bug found"); +$sel->type_ok("save_newqueryname", "selenium_m0"); +$sel->click_ok("remember"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Search created"); +my $text = trim($sel->get_text("message")); +ok($text =~ /OK, you have a new search named selenium_m0./, "New search named selenium_m0 has been created"); + +# Turn off milestones and check that the milestone field no longer appears in bugs. + +set_parameters($sel, { "Bug Fields" => {"usetargetmilestone-off" => undef} }); + +$sel->click_ok("link=Search"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Search for bugs"); +ok(!$sel->is_text_present("Target:"), "The target milestone field is no longer displayed in the search page"); + +go_to_bug($sel, $bug1_id); +ok(!$sel->is_text_present("Target Milestone:"), "The milestone field is no longer displayed in the bug page"); + +# The existing query must still work despite milestones are off now. + +$sel->click_ok("link=selenium_m0"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Bug List: selenium_m0"); +$sel->is_text_present_ok("One bug found"); +$sel->click_ok("forget_search"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Search is gone"); +$text = trim($sel->get_text("message")); +ok($text =~ /OK, the selenium_m0 search is gone./, "The selenium_m0 search is gone"); + +# Re-enable the usetargetmilestone parameter and delete the created +# milestone from the Testproduct product. + +set_parameters($sel, { "Bug Fields" => {"usetargetmilestone-on" => undef} }); + +edit_product($sel, "TestProduct"); +$sel->click_ok("link=Edit milestones:"); +$sel->wait_for_page_to_load(WAIT_TIME); +$sel->title_is("Select milestone of product 'TestProduct'"); +$sel->click_ok('//a[@href="editmilestones.cgi?action=del&product=TestProduct&milestone=TM1"]', + undef, "Deleting the TM1 milestone"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Delete Milestone of Product 'TestProduct'"); +$text = trim($sel->get_body_text()); +ok($text =~ /There is 1 bug entered for this milestone/, "Warning displayed about 1 bug targetted to TM1"); +$sel->click_ok("delete"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Milestone Deleted"); +logout($sel); diff --git a/xt/selenium/time_summary.t b/xt/selenium/time_summary.t new file mode 100644 index 000000000..f60c952ca --- /dev/null +++ b/xt/selenium/time_summary.t @@ -0,0 +1,101 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# This Source Code Form is "Incompatible With Secondary Licenses", as +# defined by the Mozilla Public License, v. 2.0. + +use 5.10.1; +use strict; +use warnings; + +use FindBin qw($RealBin); +use lib "$RealBin/../lib"; + +use Test::More "no_plan"; + +use QA::Util; + +my ($sel, $config) = get_selenium(); + +# Set the timetracking group to "editbugs", which is the default value for this parameter. + +log_in($sel, $config, 'admin'); +set_parameters($sel, { "Group Security" => {"timetrackinggroup" => {type => "select", value => "editbugs"}} }); + +# Add some Hours Worked to a bug so that we are sure at least one bug +# will be present in our buglist below. + +file_bug_in_product($sel, "TestProduct"); +$sel->select_ok("component", "TestComponent"); +my $bug_summary = "Rocket science"; +$sel->type_ok("short_desc", $bug_summary); +$sel->type_ok("comment", "Time flies"); +my $bug1_id = create_bug($sel, $bug_summary); + +$sel->type_ok("work_time", 2.6); +$sel->type_ok("comment", "I did some work"); +edit_bug_and_return($sel, $bug1_id, $bug_summary); +$sel->is_text_present_ok("I did some work"); +$sel->is_text_present_ok("Additional hours worked: 2.6"); + +# Let's call summarize_time.cgi directly, with no parameters. + +$sel->open_ok("/$config->{bugzilla_installation}/summarize_time.cgi"); +$sel->title_is("No Bugs Selected"); +my $error_msg = trim($sel->get_text("error_msg")); +ok($error_msg =~ /You apparently didn't choose any bugs for viewing/, "No data displayed"); + +# Search for bugs which have some value in the Hours Worked field. + +open_advanced_search_page($sel); +$sel->remove_all_selections("bug_status"); +$sel->select_ok("f1", "label=Hours Worked"); +$sel->select_ok("o1", "label=is greater than"); +$sel->type_ok("v1", "0"); +$sel->click_ok("Search"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Bug List"); +$sel->is_text_present_ok("found"); + +# Test dates passed to summarize_time.cgi. + +$sel->click_ok("timesummary"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_like(qr/^Time Summary \(\d+ bugs selected\)/); +$sel->check_ok("monthly"); +$sel->check_ok("detailed"); +$sel->type_ok("start_date", "2009-01-01"); +$sel->type_ok("end_date", "2009-04-30"); +$sel->click_ok("summarize"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_like(qr/^Time Summary \(\d+ bugs selected\)/); +$sel->is_text_present_ok('regexp:Total of \d+\.\d+ hours worked'); +$sel->is_text_present_ok("2009-01-01 to 2009-01-31"); +$sel->is_text_present_ok("2009-02-01 to 2009-02-28"); +$sel->is_text_present_ok("2009-04-01 to 2009-04-30"); + +$sel->type_ok("end_date", "2009-04-as"); +$sel->click_ok("summarize"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Illegal Date"); +$error_msg = trim($sel->get_text("error_msg")); +ok($error_msg =~ /'2009-04-as' is not a legal date/, "Illegal end date"); + +# Now display one bug only. We cannot do careful checks, because +# the page sums up contributions made by the same user during the same +# month, and so running this script several times per month would +# break checks we may want to do (e.g. by making sure that the contribution +# above has been taken into account). So we are just making sure that +# the page is displayed and throws no error. + +go_to_bug($sel, $bug1_id); +$sel->click_ok("//a[contains(text(),'Summarize time')]"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Time Summary for Bug $bug1_id"); +$sel->check_ok("inactive"); +$sel->check_ok("owner"); +$sel->click_ok("summarize"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Time Summary for Bug $bug1_id"); +logout($sel); diff --git a/xt/selenium/user_groups.t b/xt/selenium/user_groups.t new file mode 100644 index 000000000..aa393d47b --- /dev/null +++ b/xt/selenium/user_groups.t @@ -0,0 +1,249 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# This Source Code Form is "Incompatible With Secondary Licenses", as +# defined by the Mozilla Public License, v. 2.0. + +use 5.10.1; +use strict; +use warnings; + +use FindBin qw($RealBin); +use lib "$RealBin/../lib"; + +use Test::More "no_plan"; + +use QA::Util; + +my ($sel, $config) = get_selenium(); + +log_in($sel, $config, 'admin'); +set_parameters($sel, { "Administrative Policies" => {"allowuserdeletion-on" => undef} }); + +# First delete test users, if not deleted correctly during a previous run. + +cleanup_users($sel); + +# The Master group inherits privs of the Slave group. + +go_to_admin($sel); +$sel->click_ok("link=Groups"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Edit Groups"); +$sel->click_ok("link=Master"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Change Group: Master"); +my $group_url = $sel->get_location(); +$group_url =~ /group=(\d+)$/; +my $master_gid = $1; + +go_to_admin($sel); +$sel->click_ok("link=Groups"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Edit Groups"); +$sel->click_ok("link=Add Group"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Add group"); +$sel->type_ok("name", "Slave"); +$sel->type_ok("desc", "Members of the Master group are also members of this group"); +$sel->uncheck_ok("isactive"); +ok(!$sel->is_checked("insertnew"), "Group not added to products by default"); +$sel->click_ok("create"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("New Group Created"); +my $slave_gid = $sel->get_value("group_id"); +$sel->add_selection_ok("members_add", "label=Master"); +$sel->click_ok('//input[@value="Update Group"]'); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Change Group: Slave"); + +# Create users. + +go_to_admin($sel); +$sel->click_ok("link=Users"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is('Search users'); +$sel->click_ok('link=add a new user'); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is('Add user'); +$sel->type_ok('login', 'master@selenium.bugzilla.org'); +$sel->type_ok('name', 'master-user'); +$sel->type_ok('password', 'selenium', 'Enter password'); +$sel->type_ok('disabledtext', 'Not for common usage'); +$sel->click_ok('add'); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is('Edit user master-user <master@selenium.bugzilla.org>'); +$sel->check_ok("//input[\@name='group_$master_gid']"); +$sel->click_ok('update'); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is('User master@selenium.bugzilla.org updated'); +$sel->is_text_present_ok('The account has been added to the Master group'); + +$sel->click_ok("link=add a new user"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is('Add user'); +$sel->type_ok('login', 'slave@selenium.bugzilla.org'); +$sel->type_ok('name', 'slave-user'); +$sel->type_ok('password', 'selenium', 'Enter password'); +$sel->type_ok('disabledtext', 'Not for common usage'); +$sel->click_ok('add'); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is('Edit user slave-user <slave@selenium.bugzilla.org>'); +$sel->check_ok("//input[\@name='group_$slave_gid']"); +$sel->click_ok('update'); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is('User slave@selenium.bugzilla.org updated'); +$sel->is_text_present_ok('The account has been added to the Slave group'); + +$sel->click_ok("link=add a new user"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is('Add user'); +$sel->type_ok('login', 'reg@selenium.bugzilla.org'); +$sel->type_ok('name', 'reg-user'); +$sel->type_ok('password', 'selenium', 'Enter password'); +$sel->type_ok('disabledtext', 'Not for common usage'); +$sel->click_ok('add'); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is('Edit user reg-user <reg@selenium.bugzilla.org>'); + +# Disabled accounts are not listed by default. + +$sel->click_ok('link=find other users'); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is('Search users'); +$sel->select_ok('is_enabled', 'label=Enabled'); +$sel->click_ok('search'); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +ok(!$sel->is_text_present('master@selenium.bugzilla.org'), 'Inactive user account master-user not listed by default'); +ok(!$sel->is_text_present('slave@selenium.bugzilla.org'), 'Inactive user account slave-user not listed by default'); +ok(!$sel->is_text_present('reg@selenium.bugzilla.org'), 'Inactive user account reg-user not displayed by default'); + +# Now make sure group inheritance works correctly. + +$sel->click_ok('link=find other users'); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is('Search users'); +$sel->check_ok('grouprestrict'); +$sel->select_ok('groupid', 'label=Master'); +$sel->select_ok('matchtype', 'value=substr'); +$sel->select_ok('is_enabled', 'label=All'); +$sel->click_ok('search'); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->is_text_present_ok('master@selenium.bugzilla.org', 'master-user in Master group'); +ok(!$sel->is_text_present('slave@selenium.bugzilla.org'), 'slave-user not in Master group'); +ok(!$sel->is_text_present('reg@selenium.bugzilla.org'), 'reg-user not in Master group'); + +$sel->click_ok('link=find other users'); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is('Search users'); +$sel->check_ok('grouprestrict'); +$sel->select_ok('groupid', 'label=Slave'); +$sel->select_ok('matchtype', 'value=substr'); +$sel->select_ok('is_enabled', 'label=All'); +$sel->click_ok('search'); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->is_text_present_ok('master@selenium.bugzilla.org', 'master-user in Slave group'); +$sel->is_text_present_ok('slave@selenium.bugzilla.org', 'slave-user in Slave group'); +ok(!$sel->is_text_present('reg@selenium.bugzilla.org'), 'reg-user not in Slave group'); + +# Add a regular expression to the Slave group. + +go_to_admin($sel); +$sel->click_ok("link=Groups"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Edit Groups"); +$sel->click_ok('link=Slave'); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is('Change Group: Slave'); +$sel->type_ok('regexp', '^reg\@.*$'); +$sel->click_ok('//input[@value="Update Group"]'); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Change Group: Slave"); + +# Test group inheritance again. + +go_to_admin($sel); +$sel->click_ok("link=Users"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is('Search users'); +$sel->check_ok('grouprestrict'); +$sel->select_ok('groupid', 'label=Master'); +$sel->select_ok('matchtype', 'value=substr'); +$sel->select_ok('is_enabled', 'label=All'); +$sel->click_ok('search'); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->is_text_present_ok('master@selenium.bugzilla.org', 'master-user in Master group'); +ok(!$sel->is_text_present('slave@selenium.bugzilla.org'), 'slave-user not in Master group'); +ok(!$sel->is_text_present('reg@selenium.bugzilla.org'), 'reg-user not in Master group'); + +$sel->click_ok('link=find other users'); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is('Search users'); +$sel->check_ok('grouprestrict'); +$sel->select_ok('groupid', 'label=Slave'); +$sel->select_ok('matchtype', 'value=substr'); +$sel->select_ok('is_enabled', 'label=All'); +$sel->click_ok('search'); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->is_text_present_ok('master@selenium.bugzilla.org', 'master-user in Slave group'); +$sel->is_text_present_ok('slave@selenium.bugzilla.org', 'slave-user in Slave group'); +$sel->is_text_present_ok('reg@selenium.bugzilla.org', 'reg-user in Slave group'); + +# Remove created users and groups. + +cleanup_users($sel); +cleanup_groups($sel, $slave_gid); +logout($sel); + +sub cleanup_users { + my $sel = shift; + + go_to_admin($sel); + $sel->click_ok("link=Users"); + $sel->wait_for_page_to_load_ok(WAIT_TIME); + $sel->title_is("Search users"); + $sel->type_ok('matchstr', '(master|slave|reg)@selenium.bugzilla.org'); + $sel->select_ok('matchtype', 'value=regexp'); + $sel->select_ok('is_enabled', 'label=All'); + $sel->click_ok("search"); + $sel->wait_for_page_to_load_ok(WAIT_TIME); + $sel->title_is("Select user"); + + foreach my $user ('master', 'slave', 'reg') { + my $login = $user . '@selenium.bugzilla.org'; + next unless $sel->is_text_present($login); + + $sel->click_ok("link=$login"); + $sel->wait_for_page_to_load_ok(WAIT_TIME); + $sel->title_is("Edit user ${user}-user <$login>"); + $sel->click_ok("delete"); + $sel->wait_for_page_to_load_ok(WAIT_TIME); + $sel->title_is("Confirm deletion of user $login"); + ok(!$sel->is_text_present('You cannot delete this user account'), 'The user can be safely deleted'); + $sel->click_ok("delete"); + $sel->wait_for_page_to_load_ok(WAIT_TIME); + $sel->title_is("User $login deleted"); + $sel->click_ok('link=show the user list again'); + $sel->wait_for_page_to_load_ok(WAIT_TIME); + $sel->title_is('Select user'); + } +} + +sub cleanup_groups { + my ($sel, $slave_gid) = @_; + + go_to_admin($sel); + $sel->click_ok("link=Groups"); + $sel->wait_for_page_to_load(WAIT_TIME); + $sel->title_is("Edit Groups"); + $sel->click_ok("//a[\@href='editgroups.cgi?action=del&group=$slave_gid']"); + $sel->wait_for_page_to_load(WAIT_TIME); + $sel->title_is("Delete group 'Slave'"); + $sel->is_text_present_ok("Do you really want to delete this group?"); + ok(!$sel->is_element_present("removeusers"), 'No direct members in this group'); + $sel->click_ok("delete"); + $sel->wait_for_page_to_load(WAIT_TIME); + $sel->title_is("Group Deleted"); + $sel->is_text_present_ok("The group Slave has been deleted."); +} diff --git a/xt/selenium/user_matching.t b/xt/selenium/user_matching.t new file mode 100644 index 000000000..90c2dc608 --- /dev/null +++ b/xt/selenium/user_matching.t @@ -0,0 +1,188 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# This Source Code Form is "Incompatible With Secondary Licenses", as +# defined by the Mozilla Public License, v. 2.0. + +use 5.10.1; +use strict; +use warnings; + +use FindBin qw($RealBin); +use lib "$RealBin/../lib"; + +use Test::More "no_plan"; + +use QA::Util; + +my ($sel, $config) = get_selenium(); + +log_in($sel, $config, 'tweakparams'); +set_parameters($sel, { "User Matching" => {"usemenuforusers-off" => undef, + "maxusermatches" => {type => 'text', value => '0'}, + "confirmuniqueusermatch-on" => undef}, + "Group Security" => {"usevisibilitygroups-off" => undef} + }); + +file_bug_in_product($sel, "TestProduct"); +$sel->select_ok("component", "TestComponent"); +my $bug_summary = "Today is Tuesday"; +$sel->type_ok("short_desc", $bug_summary); +$sel->type_ok("comment", "Poker Face"); +my $bug1_id = create_bug($sel, $bug_summary); + +# We enter an incomplete email address. process_bug.cgi must ask +# for confirmation as confirmuniqueusermatch is turned on. + +$sel->click_ok("cc_edit_area_showhide"); +$sel->type_ok("newcc", $config->{unprivileged_user_login_truncated}); +$sel->click_ok("commit"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Confirm Match"); +$sel->is_text_present_ok("$config->{unprivileged_user_login_truncated} matched"); +$sel->go_back_ok(); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_like(qr/^$bug1_id/); +$sel->click_ok("cc_edit_area_showhide"); + +# We now enter a complete and valid email address, so it must be accepted. +# confirmuniqueusermatch = 1 must not trigger the confirmation page as we +# type the complete email address. + +$sel->type_ok("newcc", $config->{unprivileged_user_login}); +edit_bug_and_return($sel, $bug1_id, $bug_summary); + +# Now test wildcards ("*"). Due to confirmuniqueusermatch being turned on, +# a confirmation page must be displayed. + +$sel->click_ok("cc_edit_area_showhide"); +$sel->type_ok("newcc", "$config->{unprivileged_user_login_truncated}*"); +$sel->click_ok("commit"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Confirm Match"); +$sel->is_text_present_ok("<$config->{unprivileged_user_login}>"); +$sel->go_back_ok(); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_like(qr/^$bug1_id/); +$sel->click_ok("cc_edit_area_showhide"); + +# This will return more than one account. + +$sel->type_ok("newcc", "*$config->{common_email}"); +$sel->click_ok("commit"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Confirm Match"); +$sel->is_text_present_ok("*$config->{common_email} matched:"); + +# Now restrict 'maxusermatches'. + +set_parameters($sel, { "User Matching" => {"maxusermatches" => {type => 'text', value => '1'}} }); + +go_to_bug($sel, $bug1_id); +$sel->click_ok("cc_edit_area_showhide"); + +# Several user accounts match this partial email address. Due to +# maxusermatches = 1, no email address is suggested. + +$sel->type_ok("newcc", "*$config->{common_email}"); +$sel->click_ok("commit"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Match Failed"); +$sel->is_text_present_ok("matches multiple users"); +$sel->go_back_ok(); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_like(qr/^$bug1_id/); +$sel->click_ok("cc_edit_area_showhide"); + +# We now type a complete and valid email address, so no confirmation +# page should be displayed. + +$sel->type_ok("newcc", $config->{unprivileged_user_login}); +edit_bug($sel, $bug1_id, $bug_summary); + +# Now turn on group visibility. It involves important security checks. + +set_parameters($sel, { "User Matching" => {"maxusermatches" => {type => 'text', value => '2'}}, + "Group Security" => {"usevisibilitygroups-on" => undef} + }); + +# By default, groups are not visible to themselves, so we have to enable this. +# The tweakparams user has not enough privs to do it himself. + +logout($sel); +log_in($sel, $config, 'admin'); +go_to_admin($sel); +$sel->click_ok("link=Groups"); +$sel->wait_for_page_to_load(WAIT_TIME); +$sel->title_is("Edit Groups"); +$sel->click_ok("link=tweakparams"); +$sel->wait_for_page_to_load(WAIT_TIME); +$sel->title_is("Change Group: tweakparams"); + +my @groups = $sel->get_select_options("visible_from_add"); +if (grep {$_ eq 'tweakparams'} @groups) { + $sel->add_selection_ok("visible_from_add", "label=tweakparams"); + $sel->click_ok('//input[@value="Update Group"]'); + $sel->wait_for_page_to_load_ok(WAIT_TIME); + $sel->title_is("Change Group: tweakparams"); +} +logout($sel); +log_in($sel, $config, 'tweakparams'); + +go_to_bug($sel, $bug1_id); +$sel->click_ok("cc_edit_area_showhide"); + +# We are not in the same groups as the unprivileged user, so we cannot see him. + +$sel->type_ok("newcc", $config->{unprivileged_user_login_truncated}); +$sel->click_ok("commit"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Match Failed"); +$sel->is_text_present_ok("$config->{unprivileged_user_login_truncated} did not match anything"); +$sel->go_back_ok(); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_like(qr/^$bug1_id/); +$sel->click_ok("cc_edit_area_showhide"); + +# This will return too many users (there are at least always three: +# you, the admin and the permanent user (who has admin privs too)). + +$sel->type_ok("newcc", $config->{common_email}); +$sel->click_ok("commit"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Confirm Match"); +$sel->is_text_present_ok("$config->{common_email} matched more than the maximum of 2 users"); +$sel->go_back_ok(); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_like(qr/^$bug1_id/); +$sel->click_ok("cc_edit_area_showhide"); + +# We can always see ourselves. + +$sel->type_ok("newcc", $config->{tweakparams_user_login_truncated}); +$sel->click_ok("commit"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Confirm Match"); +$sel->is_text_present_ok("<$config->{tweakparams_user_login}>"); + +# Now test user menus. It must NOT display users we are not allowed to see. + +set_parameters($sel, { "User Matching" => {"usemenuforusers-on" => undef} }); + +go_to_bug($sel, $bug1_id); +$sel->click_ok("cc_edit_area_showhide"); +my @cc = $sel->get_select_options("newcc"); +ok(!grep($_ =~ /$config->{unprivileged_user_login}/, @cc), "$config->{unprivileged_user_login} is not visible"); +ok(!grep($_ =~ /$config->{canconfirm_user_login}/, @cc), "$config->{canconfirm_user_login} is not visible"); +ok(grep($_ =~ /$config->{admin_user_login}/, @cc), "$config->{admin_user_login} is visible"); +ok(grep($_ =~ /$config->{tweakparams_user_login}/, @cc), "$config->{tweakparams_user_login} is visible"); + +# Reset paramters. + +set_parameters($sel, { "User Matching" => {"usemenuforusers-off" => undef, + "maxusermatches" => {type => 'text', value => '0'}, + "confirmuniqueusermatch-off" => undef}, + "Group Security" => {"usevisibilitygroups-off" => undef} + }); +logout($sel); diff --git a/xt/selenium/user_preferences.t b/xt/selenium/user_preferences.t new file mode 100644 index 000000000..0d7d87a5c --- /dev/null +++ b/xt/selenium/user_preferences.t @@ -0,0 +1,225 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# This Source Code Form is "Incompatible With Secondary Licenses", as +# defined by the Mozilla Public License, v. 2.0. + +use 5.10.1; +use strict; +use warnings; + +use FindBin qw($RealBin); +use lib "$RealBin/../lib"; + +use Test::More "no_plan"; + +use QA::Util; + +my ($sel, $config) = get_selenium(); + +# Update default user preferences. + +log_in($sel, $config, 'admin'); +go_to_admin($sel); +$sel->click_ok("link=Default Preferences"); +$sel->wait_for_page_to_load(WAIT_TIME); +$sel->title_is("Default Preferences"); +$sel->uncheck_ok("skin-enabled"); +$sel->value_is("skin-enabled", "off"); +$sel->check_ok("state_addselfcc-enabled"); +$sel->select_ok("state_addselfcc", "label=Never"); +$sel->check_ok("post_bug_submit_action-enabled"); +$sel->select_ok("post_bug_submit_action", "label=Show the updated bug"); +$sel->uncheck_ok("zoom_textareas-enabled"); +$sel->select_ok("zoom_textareas", "label=Off"); +$sel->click_ok("update"); +$sel->wait_for_page_to_load(WAIT_TIME); +$sel->title_is("Default Preferences"); + +# Update own user preferences. Some of them are not editable. + +$sel->click_ok("link=Preferences"); +$sel->wait_for_page_to_load(WAIT_TIME); +$sel->title_is("General Preferences"); +ok(!$sel->is_editable("skin"), "The 'skin' user preference is not editable"); +$sel->select_ok("state_addselfcc", "label=Site Default (Never)"); +$sel->select_ok("post_bug_submit_action", "label=Site Default (Show the updated bug)"); +ok(!$sel->is_editable("zoom_textareas"), "The 'zoom_textareas' user preference is not editable"); +$sel->click_ok("update"); +$sel->wait_for_page_to_load(WAIT_TIME); +$sel->title_is("General Preferences"); + +# File a bug in the 'TestProduct' product. The form fields must follow user prefs. + +file_bug_in_product($sel, 'TestProduct'); +$sel->value_is("cc", ""); +my $bug_summary = "First bug created"; +$sel->type_ok("short_desc", $bug_summary); +$sel->type_ok("comment", "I'm not in the CC list."); +my $bug1_id = create_bug($sel, $bug_summary); + +$sel->value_is("addselfcc", "off"); +$sel->type_ok("tag", "sel-tmp"); +$sel->select_ok("bug_status", "label=IN_PROGRESS"); +edit_bug($sel, $bug1_id, $bug_summary); +$sel->click_ok("summary_edit_action"); +$sel->value_is("short_desc", $bug_summary); +$sel->value_is("addselfcc", "off"); + +# Create a saved search for the 'sel-tmp' tag. + +$sel->type_ok("quicksearch_top", "tag:sel-tmp"); +$sel->click_ok("find_top"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Bug List"); +$sel->type_ok("save_newqueryname", "sel-tmp"); +$sel->click_ok("remember"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Search created"); +$sel->is_text_present_ok("OK, you have a new search named sel-tmp"); + +# Leave this page to avoid clicking on the wrong 'sel-tmp' link. +go_to_home($sel, $config); +$sel->click_ok("link=sel-tmp"); +$sel->wait_for_page_to_load(WAIT_TIME); +$sel->title_is("Bug List: sel-tmp"); +$sel->is_text_present_ok("One bug found"); + +# File another bug in the 'TestProduct' product. + +file_bug_in_product($sel, 'TestProduct'); +$sel->value_is("cc", ""); +my $bug_summary2 = "My second bug"; +$sel->type_ok("short_desc", $bug_summary2); +$sel->type_ok("comment", "Still not in the CC list"); +my $bug2_id = create_bug($sel, $bug_summary2); +$sel->value_is("addselfcc", "off"); +$sel->type_ok("tag", "sel-tmp"); +edit_bug($sel, $bug2_id, $bug_summary2); + +$sel->click_ok("link=sel-tmp"); +$sel->wait_for_page_to_load(WAIT_TIME); +$sel->title_is("Bug List: sel-tmp"); +$sel->is_text_present_ok("2 bugs found"); +$sel->click_ok("link=$bug1_id"); +$sel->wait_for_page_to_load(WAIT_TIME); +$sel->title_like(qr/^$bug1_id /); +$sel->type_ok("comment", "The next bug I should see is this one."); +edit_bug($sel, $bug1_id, $bug_summary); +$sel->click_ok("summary_edit_action"); +$sel->value_is("short_desc", "First bug created"); +$sel->is_text_present_ok("The next bug I should see is this one."); + +# Remove the saved search. The tag itself still exists. + +$sel->click_ok("link=sel-tmp"); +$sel->wait_for_page_to_load(WAIT_TIME); +$sel->title_is("Bug List: sel-tmp"); +$sel->click_ok("forget_search"); +$sel->wait_for_page_to_load(WAIT_TIME); +$sel->title_is("Search is gone"); +$sel->is_text_present_ok("OK, the sel-tmp search is gone"); + +# Remove the tag from bugs. + +$sel->type_ok("quicksearch_top", "tag:sel-tmp"); +$sel->click_ok("find_top"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Bug List"); +$sel->is_text_present_ok("2 bugs found"); +# We cannot remove tags from several bugs at once (bug 791584). +go_to_bug($sel, $bug1_id); +$sel->type_ok("tag", ""); +edit_bug($sel, $bug1_id, $bug_summary); + +go_to_bug($sel, $bug2_id); +$sel->type_ok("tag", ""); +edit_bug($sel, $bug2_id, $bug_summary2); + +$sel->type_ok("quicksearch_top", "tag:sel-tmp"); +$sel->click_ok("find_top"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Bug List"); +$sel->is_text_present_ok("Zarro Boogs found"); +logout($sel); + +# Edit own user preferences, now as an unprivileged user. + +log_in($sel, $config, 'unprivileged'); +$sel->click_ok("link=Preferences"); +$sel->wait_for_page_to_load(WAIT_TIME); +$sel->title_is("General Preferences"); +ok(!$sel->is_editable("skin"), "The 'skin' user preference is not editable"); +$sel->select_ok("state_addselfcc", "label=Always"); +$sel->select_ok("post_bug_submit_action", "label=Show next bug in my list"); +ok(!$sel->is_editable("zoom_textareas"), "The 'zoom_textareas' user preference is not editable"); +$sel->click_ok("update"); +$sel->wait_for_page_to_load(WAIT_TIME); +$sel->title_is("General Preferences"); + +# Create a new search named 'my_list'. + +open_advanced_search_page($sel); +$sel->remove_all_selections_ok("product"); +$sel->add_selection_ok("product", "TestProduct"); +$sel->remove_all_selections_ok("bug_status"); +$sel->select_ok("bug_id_type", "label=only included in"); +$sel->type_ok("bug_id", "$bug1_id , $bug2_id"); +$sel->select_ok("order", "label=Bug Number"); +$sel->click_ok("Search"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Bug List"); +$sel->is_text_present_ok("2 bugs found"); +$sel->type_ok("save_newqueryname", "my_list"); +$sel->click_ok("remember"); +$sel->wait_for_page_to_load(WAIT_TIME); +$sel->title_is("Search created"); +$sel->is_text_present_ok("OK, you have a new search named my_list"); + +# Editing bugs should follow user preferences. + +$sel->click_ok("link=my_list"); +$sel->wait_for_page_to_load(WAIT_TIME); +$sel->title_is("Bug List: my_list"); +$sel->click_ok("link=$bug1_id"); +$sel->wait_for_page_to_load(WAIT_TIME); +$sel->title_like(qr/^$bug1_id /); +$sel->value_is("addselfcc", "on"); +$sel->type_ok("comment", "I should be CC'ed and then I should see the next bug."); +edit_bug($sel, $bug2_id, $bug_summary2); +$sel->is_text_present_ok("The next bug in your list is bug $bug2_id"); +ok(!$sel->is_text_present("I should see the next bug"), "The updated bug is no longer displayed"); +# The user has no privs, so the short_desc field is not present. +$sel->is_text_present("short_desc", "My second bug"); +$sel->value_is("addselfcc", "on"); +$sel->click_ok("link=$bug1_id"); +$sel->wait_for_page_to_load(WAIT_TIME); +$sel->title_like(qr/^$bug1_id /); +$sel->is_text_present("1 user including you"); + +# Delete the saved search and log out. + +$sel->click_ok("link=my_list"); +$sel->wait_for_page_to_load(WAIT_TIME); +$sel->title_is("Bug List: my_list"); +$sel->click_ok("forget_search"); +$sel->wait_for_page_to_load(WAIT_TIME); +$sel->title_is("Search is gone"); +$sel->is_text_present_ok("OK, the my_list search is gone"); +logout($sel); + +# Restore default user preferences. + +log_in($sel, $config, 'admin'); +go_to_admin($sel); +$sel->click_ok("link=Default Preferences"); +$sel->wait_for_page_to_load(WAIT_TIME); +$sel->title_is("Default Preferences"); +$sel->check_ok("skin-enabled"); +$sel->uncheck_ok("post_bug_submit_action-enabled"); +$sel->select_ok("post_bug_submit_action", "label=Do Nothing"); +$sel->click_ok("update"); +$sel->wait_for_page_to_load(WAIT_TIME); +$sel->title_is("Default Preferences"); +logout($sel); diff --git a/xt/selenium/user_privs.t b/xt/selenium/user_privs.t new file mode 100644 index 000000000..f48792839 --- /dev/null +++ b/xt/selenium/user_privs.t @@ -0,0 +1,60 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# This Source Code Form is "Incompatible With Secondary Licenses", as +# defined by the Mozilla Public License, v. 2.0. + +use 5.10.1; +use strict; +use warnings; + +use FindBin qw($RealBin); +use lib "$RealBin/../lib"; + +use Test::More "no_plan"; + +use QA::Util; + +my ($sel, $config) = get_selenium(); + +# Create a new bug. As the reporter, some forms are editable to you. +# But as you don't have editbugs privs, you cannot edit everything. + +log_in($sel, $config, 'unprivileged'); +file_bug_in_product($sel, 'TestProduct'); +ok(!$sel->is_editable("assigned_to"), "The assignee field is not editable"); +my $bug_summary = "Greetings from a powerless user"; +$sel->type_ok("short_desc", $bug_summary); +$sel->type_ok("comment", "File a bug with an empty CC list"); +my $bug1_id = create_bug($sel, $bug_summary); +logout($sel); + +# Some checks while being logged out. + +go_to_bug($sel, $bug1_id); +ok(!$sel->is_element_present("commit"), "Button 'Commit' not available"); +my $text = trim($sel->get_text("//fieldset")); +ok($text =~ /You need to log in before you can comment on or make changes to this bug./, + "Addl. comment box not displayed"); + +# Don't call log_in() here. We explicitly want to use the "log in" link +# in the addl. comment box. + +$sel->click_ok("link=log in"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Log in to Bugzilla"); +$sel->is_text_present_ok("Bugzilla needs a legitimate login and password to continue"); +$sel->type_ok("Bugzilla_login", $config->{unprivileged_user_login}, "Enter login name"); +$sel->type_ok("Bugzilla_password", $config->{unprivileged_user_passwd}, "Enter password"); +$sel->click_ok("log_in", undef, "Submit credentials"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_like(qr/^$bug1_id/, "Display bug $bug1_id"); + +# Neither the (edit) link nor the hidden form must exist, at all. +# But the 'Commit' button does exist. + +ok(!$sel->is_element_present("bz_assignee_edit_action"), "No (edit) link displayed for the assignee"); +ok(!$sel->is_element_present("assigned_to"), "No hidden assignee field available"); +$sel->is_element_present_ok("commit"); +logout($sel); diff --git a/xt/selenium/votes.t b/xt/selenium/votes.t new file mode 100644 index 000000000..e5a7c853d --- /dev/null +++ b/xt/selenium/votes.t @@ -0,0 +1,233 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# This Source Code Form is "Incompatible With Secondary Licenses", as +# defined by the Mozilla Public License, v. 2.0. + +use 5.10.1; +use strict; +use warnings; + +use FindBin qw($RealBin); +use lib "$RealBin/../lib"; + +use Test::More "no_plan"; + +use QA::Util; + +my ($sel, $config) = get_selenium(); + +unless ($config->{test_extensions}) { + ok(1, "this installation doesn't test extensions. Skipping test_votes.t completely."); + exit; +} + +log_in($sel, $config, 'admin'); +set_parameters($sel, { "Bug Fields" => {"useclassification-off" => undef}, + "Administrative Policies" => {"allowbugdeletion-on" => undef} + }); + +# Create a new product, so that we can safely play with vote settings. + +add_product($sel); +$sel->type_ok("product", "Eureka"); +$sel->type_ok("description", "A great new product"); +$sel->type_ok("votesperuser", 10); +$sel->type_ok("maxvotesperbug", 5); +$sel->type_ok("votestoconfirm", 3); +$sel->type_ok("component", "Pegasus"); +$sel->type_ok("comp_desc", "A constellation in the north hemisphere."); +$sel->type_ok("initialowner", $config->{permanent_user}, "Setting the default owner"); +$sel->click_ok('add-product'); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Product Created"); + +# Create a new bug with the CONFIRMED status. + +file_bug_in_product($sel, 'Eureka'); +# CONFIRMED must be the default bug status for users with editbugs privs. +$sel->selected_label_is("bug_status", "CONFIRMED"); +my $bug_summary = "Aries"; +$sel->type_ok("short_desc", $bug_summary); +$sel->type_ok("comment", "1st constellation"); +my $bug1_id = create_bug($sel, $bug_summary); + +# Now vote for this bug. + +$sel->click_ok("link=vote"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Change Votes"); +# No comment :-/ +my $full_text = trim($sel->get_body_text()); +# OK, this is not the most robust regexp, but that's better than nothing. +ok($full_text =~ /only 5 votes allowed per bug in this product/, + "Notice about the number of votes allowed per bug displayed"); +$sel->type_ok("bug_$bug1_id", 4); +$sel->click_ok("change"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Change Votes"); +$full_text = trim($sel->get_body_text()); +# OK, we may get a false positive if another product has the exact same numbers, +# but I have no better idea to check this information. +ok($full_text =~ /4 votes used out of 10 allowed/, "Display the number of votes used"); + +# File a new bug, now as UNCONFIRMED. We will confirm it by popular votes. + +file_bug_in_product($sel, 'Eureka'); +$sel->select_ok("bug_status", "UNCONFIRMED"); +my $bug_summary2 = "Taurus"; +$sel->type_ok("short_desc", $bug_summary2); +$sel->type_ok("comment", "2nd constellation"); +my $bug2_id = create_bug($sel, $bug_summary2); + +# Put enough votes on this bug to confirm it by popular votes. + +$sel->click_ok("link=vote"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Change Votes"); +$sel->type_ok("bug_$bug2_id", 5); +$sel->click_ok("change"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Change Votes"); +$sel->is_text_present_ok("Bug $bug2_id confirmed by number of votes"); + +# File a third bug, again as UNCONFIRMED. We will confirm it +# by decreasing the number required to confirm bugs by popular votes. + +file_bug_in_product($sel, 'Eureka'); +$sel->select_ok("bug_status", "UNCONFIRMED"); +my $bug_summary3 = "Gemini"; +$sel->type_ok("short_desc", $bug_summary3); +$sel->type_ok("comment", "3rd constellation"); +my $bug3_id = create_bug($sel, $bug_summary3); + +# Vote for this bug, but remain below the threshold required +# to confirm the bug by popular votes. +# We also change votes set on other bugs for testing purposes. + +$sel->click_ok("link=vote"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Change Votes"); +$sel->type_ok("bug_$bug1_id", 2); +$sel->type_ok("bug_$bug3_id", 2); +$sel->click_ok("change"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Change Votes"); +# Illegal change: max is 5 votes per bug! +$sel->type_ok("bug_$bug2_id", 15); +$sel->click_ok("change"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Illegal Vote"); +my $text = trim($sel->get_text("error_msg")); +ok($text =~ /You may only use at most 5 votes for a single bug in the Eureka product, but you are trying to use 15/, + "Too many votes per bug"); + +# FIXME - We cannot use go_back_ok() here, because Firefox complains about +# POST data not being stored in its cache. As a workaround, we go to +# the bug we just visited and click the 'vote' link again. + +go_to_bug($sel, $bug3_id); +$sel->click_ok("link=vote"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Change Votes"); + +# Illegal change: max is 10 votes for this product! +$sel->type_ok("bug_$bug2_id", 5); +$sel->type_ok("bug_$bug1_id", 5); +$sel->click_ok("change"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Illegal Vote"); +$text = trim($sel->get_text("error_msg")); +ok($text =~ /You tried to use 12 votes in the Eureka product, which exceeds the maximum of 10 votes for this product/, + "Too many votes for this product"); + +# Decrease the confirmation threshold so that $bug3 becomes confirmed. + +edit_product($sel, 'Eureka'); +$sel->type_ok("votestoconfirm", 2); +$sel->click_ok("update-product"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Updating Product 'Eureka'"); +$full_text = trim($sel->get_body_text()); +ok($full_text =~ /Updated number of votes needed to confirm a bug from 3 to 2/, + "Confirming the new number of votes to confirm"); +$sel->is_text_present_ok("Bug $bug3_id confirmed by number of votes"); + +# Decrease the number of votes per bug so that $bug2 is updated. + +$sel->click_ok("link='Eureka'"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Edit Product 'Eureka'"); +$sel->type_ok("maxvotesperbug", 4); +$sel->click_ok("update-product"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Updating Product 'Eureka'"); +$full_text = trim($sel->get_body_text()); +ok($full_text =~ /Updated maximum votes per bug from 5 to 4/, "Confirming the new number of votes per bug"); +$sel->is_text_present_ok("removed votes for bug $bug2_id from " . $config->{admin_user_login}, undef, + "Removed votes from the admin"); + +# Go check that $bug2 has been correctly updated. + +$sel->click_ok("link=$bug2_id"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_like(qr/$bug2_id /); +$text = trim($sel->get_text("votes_container")); +ok($text =~ /4 votes/, "4 votes remaining"); + +# Decrease the number per user. Bugs should keep at least one vote, +# i.e. not all votes are removed (which was the old behavior). + +edit_product($sel, "Eureka"); +$sel->type_ok("votesperuser", 5); +$sel->click_ok("update-product"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Updating Product 'Eureka'"); +$full_text = trim($sel->get_body_text()); +ok($full_text =~ /Updated votes per user from 10 to 5/, "Confirming the new number of votes per user"); +$sel->is_text_present_ok("removed votes for bug"); + +# Go check that $bug3 has been correctly updated. + +$sel->click_ok("link=$bug3_id"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_like(qr/$bug3_id /); +$text = trim($sel->get_text("votes_container")); +ok($text =~ /2 votes/, "2 votes remaining"); + +# Now disable UNCONFIRMED. + +edit_product($sel, "Eureka"); +$sel->click_ok("allows_unconfirmed"); +$sel->click_ok("update-product"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Updating Product 'Eureka'"); +$full_text = trim($sel->get_body_text()); +ok($full_text =~ /The product no longer allows the UNCONFIRMED status/, "Disable UNCONFIRMED"); + +# File a new bug. UNCONFIRMED must not be listed as a valid bug status. + +file_bug_in_product($sel, "Eureka"); +ok(!scalar(grep {$_ eq "UNCONFIRMED"} $sel->get_select_options("bug_status")), "UNCONFIRMED not listed"); +my $bug_summary4 = "Cancer"; +$sel->type_ok("short_desc", $bug_summary4); +$sel->type_ok("comment", "4th constellation"); +my $bug4_id = create_bug($sel, $bug_summary4); + +# Now delete the 'Eureka' product. + +go_to_admin($sel); +$sel->click_ok("link=Products"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Select product"); +$sel->click_ok('//a[@href="editproducts.cgi?action=del&product=Eureka"]'); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Delete Product 'Eureka'"); +$full_text = trim($sel->get_body_text()); +ok($full_text =~ /There are 4 bugs entered for this product/, "Display warning about existing bugs"); +ok($full_text =~ /Pegasus: A constellation in the north hemisphere/, "Display product description"); +$sel->click_ok("delete"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Product Deleted"); +logout($sel); |