diff --git a/config/bugzilla.conf b/config/bugzilla.conf index c4f00b3..069bda9 100644 --- a/config/bugzilla.conf +++ b/config/bugzilla.conf @@ -1,7 +1,7 @@ - DocumentRoot %TRAVIS_BUILD_DIR% - Alias /bugzilla %TRAVIS_BUILD_DIR% - + DocumentRoot /home/bugzilla/devel/htdocs + Alias /bugzilla /home/bugzilla/devel/htdocs + AddHandler cgi-script .cgi Options +Indexes +ExecCGI +FollowSymLinks DirectoryIndex index.cgi diff --git a/config/config-checksetup-mysql b/config/config-checksetup-mysql deleted file mode 100755 index a0b5b31..0000000 --- a/config/config-checksetup-mysql +++ /dev/null @@ -1,119 +0,0 @@ -use strict; -use warnings; - -use constant CONFIG => { - base_dir => '%TRAVIS_BUILD_DIR%', - test_db => 'bugs_checksetup', - tip_db => 'bugs_tip', - db_type => 'MySQL', - db_user => 'bugs', - db_pass => 'bugs', - answers => 'qa/config/checksetup_answers.txt', - test_user_login => 'checksetup_test_user@my.company', - test_real_name => 'Checksetup Test User', - dump_file_url => 'https://people.mozilla.org/~dkl/tinderbox/dumps/mysql', - - # Databases bugs_tip and bugs_bugzilla4_[024]_branch are replicated from - # landfill so no need to copy them manually (which takes about 500+200 sec) - #copy_dbs => [qw()], - # - # I don't think there are going to be any more DB changes on - # these branches. - # bugs_bugzilla3_4_branch - # bugs_bugzilla3_2_branch - # bugs_bugzilla3_0_branch - # bugs_bugzilla2_22_branch - # bugs_bugzilla2_20_branch - # bugs_bugzilla2_18_branch - # - # All odd-numbered versions are development releases and won't be tested - # because we don't support upgrades from them and this saves test cycles. - # - # Due to hd crash, we lost test databases marked with #### - # - db_list => { - # This is 2.08 so that it sorts properly. - # Upgrades from 2.8 are no longer supported. - #'2.08' => 'bugs_2_8', -#### '2.09' => 'bugs_2_9', -#### '2.10' => 'bugs_2_10', -#### '2.12' => 'bugs_2_12', -#### '2.13' => 'bugs_2_13', -#### '2.14' => 'bugs_2_14', - '2.14.1' => 'bugs_2_14_1', - '2.14.2' => 'bugs_2_14_2', - '2.14.x' => 'bugs_2_14_branch', - '2.16' => 'bugs_2_16', -#### '2.16.1' => 'bugs_2_16_1_ru', -#### '2.16.3' => 'bugs_2_16_3', -#### '2.16.4' => 'bugs_2_16_4', -#### '2.16.5' => 'bugs_2_16_5', -#### '2.16.6' => 'bugs_2_16_6', -#### '2.16.11' => 'bugs_2_16_11', - '2.16.x' => 'bugs_2_16_branch', - #'2.17.1' => 'bugs_2_17_1', - #'2.17.3' => 'bugs_2_17_3', - #'2.17.4' => 'bugs_2_17_4es', - #'2.17.5' => 'bugs_2_17_5', - #'2.17.6' => 'bugs_2_17_6', - #'2.17.7' => 'bugs_2_17_7', -#### '2.18rc1' => 'bugs_2_18_rc1', - # There were no significant checksetup changes between 2.18rc1 and 2.18rc2 -#### '2.18rc3' => 'bugs_2_18_rc3', -#### '2.18.1' => 'bugs_2_18_1', -#### '2.18.2' => 'bugs_2_18_2', -#### '2.18.4' => 'bugs_2_18_4', -#### '2.18.5' => 'bugs_2_18_5', - '2.18.x' => 'bugs_2_18_branch', - #'2.19.1' => 'bugs_2_19_1', - # 2.19.2 was during the "original 2.20 freeze", so no important changes. - #'2.19.3' => 'bugs_2_19_3', -#### '2.20rc1' => 'bugs_2_20rc1', -#### '2.20rc2' => 'bugs_2_20rc2', -#### '2.20' => 'bugs_2_20', -#### '2.20.1' => 'bugs_2_20_1', - # No checksetup changes in 2.20.2-2.20.4. - '2.20.x' => 'bugs_2_20_branch', - #'2.21.1' => 'bugs_2_21', -#### '2.22rc1' => 'bugs_2_22rc1', - # No difference in checksetup between 2.22rc1 and 2.22. -#### '2.22.1' => 'bugs_2_22_1', - '2.22.x' => 'bugs_2_22_branch', - #'2.23.1' => 'bugs_2_23_1', - #'2.23.2' => 'bugs_2_23_2', - #'2.23.3' => 'bugs_2_23_3', - #'2.23.4' => 'bugs_2_23_4', -#### '3.0' => 'bugs_3_0', - # No difference in checksetup between 3.0 and 3.0.1 - '3.0.x' => 'bugs_3_0_branch', - #'3.1.1' => 'bugs_3_1_1', - #'3.1.2' => 'bugs_3_1_2', - #'3.1.4' => 'bugs_3_1_4', -#### '3.2rc1' => 'bugs_3_2rc1', - # No DB changes between 3.2rc1 and 3.2 - '3.2.x' => 'bugs_3_2_branch', - #'3.3.1' => 'bugs_3_3_1', - #'3.3.4' => 'bugs_3_3_4', - '3.4.x' => 'bugs_3_4_branch', - #'3.5.1' => 'bugs_3_5_1', - #'3.5.3' => 'bugs_3_5_3', -#### '3.6' => 'bugs_3_6', - '3.6.x' => 'bugs_3_6_branch', - #'3.7.1' => 'bugs_3_7_1', - #'3.7.2' => 'bugs_3_7_2', - #'3.7.3' => 'bugs_3_7_3', -#### '4.0.11' => 'bugs_4_0_11', - '4.0.x' => 'bugs_4_0_branch', - #'4.1.1' => 'bugs_4_1_1', - # No DB changes between 4.1.1 and 4.1.2 - #'4.1.3' => 'bugs_4_1_3', -#### '4.2rc1' => 'bugs_4_2rc1', -#### '4.2.7' => 'bugs_4_2_7', - '4.2.x' => 'bugs_4_2_branch', - # No DB changes between 4.4rc2 and 4.4 or 4.4 and 4.4.1 -#### '4.4.1' => 'bugs_4_4_1', - '4.4.x' => 'bugs_4_4_branch', - }, -}; - -1; diff --git a/config/config-checksetup-pg b/config/config-checksetup-pg deleted file mode 100755 index 30baa48..0000000 --- a/config/config-checksetup-pg +++ /dev/null @@ -1,38 +0,0 @@ -use strict; -use warnings; - -use constant CONFIG => { - base_dir => '%TRAVIS_BUILD_DIR%', - test_db => 'bugs_checksetup', - tip_db => 'bugs_tip', - db_type => 'Pg', - db_user => 'bugs', - db_pass => 'bugs', - answers => '/home/tinderbox/answers', - answers => 'qa/config/checksetup_answers.txt', - test_user_login => 'checksetup_test_user@my.company', - test_real_name => 'Checksetup Test User', - dump_file_url => 'https://people.mozilla.org/~dkl/tinderbox/dumps/pg', - db_list => { - '2.20.x' => 'bugs_bugzilla2_20_branch', - '2.22.x' => 'bugs_bugzilla2_22_branch', - '2.23.2' => 'bugs_2_23_2', - '2.23.4' => 'bugs_2_23_4', - '3.0' => 'bugs_3_0', - '3.1.1' => 'bugs_3_1_1', - '3.1.3' => 'bugs_3_1_3', - '3.1.4' => 'bugs_3_1_4', - '3.2rc1' => 'bugs_3_2rc1', - '3.3.1' => 'bugs_3_3_1', - '3.3.4' => 'bugs_3_3_4', - '3.5.1' => 'bugs_3_5_1', - '3.5.3' => 'bugs_3_5_3', - '3.7.1' => 'bugs_3_7_1', - '3.7.2' => 'bugs_3_7_2', - '4.1.1' => 'bugs_4_1_1', - '4.1.3' => 'bugs_4_1_3', - '4.2rc1' => 'bugs_4_2rc1', - }, -}; - -1; diff --git a/config/generate_test_data.pl b/config/generate_test_data.pl old mode 100644 new mode 100755 index 6055231..db82a82 --- a/config/generate_test_data.pl +++ b/config/generate_test_data.pl @@ -1,6 +1,7 @@ -#!/usr/bin/perl -w +#!/usr/bin/perl # -*- Mode: perl; indent-tabs-mode: nil -*- +use 5.10.1; use strict; use warnings; @@ -10,12 +11,16 @@ my $config; BEGIN { - print "reading the config file...\n"; - my $conf_file = "selenium_test.conf"; + say 'reading the config file...'; + my $conf_file = 'selenium_test.conf'; $config = do "$conf_file" or die "can't read configuration '$conf_file': $!$@"; $conf_path = $config->{bugzilla_path}; + + # We don't want randomly-generated keys. We want the ones specified + # in the config file so that we can use them in tests scripts. + *Bugzilla::User::APIKey::_check_api_key = sub { return $_[1]; }; } use lib $conf_path; @@ -34,6 +39,7 @@ BEGIN use Bugzilla::Keyword; use Bugzilla::Config qw(:admin); use Bugzilla::User::Setting; +use Bugzilla::User::APIKey; my $dbh = Bugzilla->dbh; @@ -90,8 +96,9 @@ BEGIN ########################################################################## # Create Users ########################################################################## + # First of all, remove the default .* regexp for the editbugs group. -my $group = new Bugzilla::Group({ name => 'editbugs' }); +my $group = Bugzilla::Group->new({ name => 'editbugs' }); $group->set_user_regexp(''); $group->update(); @@ -102,45 +109,49 @@ BEGIN 'editbugs', 'disabled', ); -print "creating user accounts...\n"; -for my $username (@usernames) { +say 'creating user accounts...'; +foreach my $username (@usernames) { + my ($password, $login); - my $password; - my $login; - + my $prefix = $username; if ($username eq 'permanent_user') { $password = $config->{admin_user_passwd}; $login = $config->{$username}; } elsif ($username eq 'no-privs') { - $password = $config->{unprivileged_user_passwd}; - $login = $config->{unprivileged_user_login}; + $prefix = 'unprivileged'; } elsif ($username eq 'QA-Selenium-TEST') { - $password = $config->{QA_Selenium_TEST_user_passwd}; - $login = $config->{QA_Selenium_TEST_user_login}; - } - else { - $password = $config->{"$username" . "_user_passwd"}; - $login = $config->{"$username" . "_user_login"}; + $prefix = 'QA_Selenium_TEST'; } - if ( is_available_username($login) ) { - my %extra_args; - if ($username eq 'disabled') { - $extra_args{disabledtext} = '!!This is the text!!'; - } - - Bugzilla::User->create( - { login_name => $login, - realname => $username, - cryptpassword => $password, - %extra_args, + $password ||= $config->{"${prefix}_user_passwd"}; + $login ||= $config->{"${prefix}_user_login"}; + my $api_key = $config->{"${prefix}_user_api_key"}; + + if (is_available_username($login)) { + my %extra_args; + if ($username eq 'disabled') { + $extra_args{disabledtext} = '!!This is the text!!'; + } + + my $user = Bugzilla::User->create( + { login_name => $login, + realname => $username, + cryptpassword => $password, + %extra_args, } ); - if ( $username eq 'admin' or $username eq 'permanent_user' ) { + if ($api_key) { + Bugzilla::User::APIKey->create( + { user_id => $user->id, + description => 'API key for QA tests', + api_key => $api_key } + ); + } + if ($username eq 'admin' or $username eq 'permanent_user') { Bugzilla::Install::make_admin($login); } } @@ -168,32 +179,36 @@ BEGIN 'bug_severity' => 'normal', ); -print "creating bugs...\n"; -Bugzilla::Bug->create( \%field_values ); +say 'creating bugs...'; +my $bug = Bugzilla::Bug->create( \%field_values ); +say 'Bug ' . $bug->id . ' created'; if (Bugzilla::Bug->new('public_bug')->{error}) { # The deadline must be set so that this bug can be used to test # timetracking fields using WebServices. - Bugzilla::Bug->create({ %field_values, alias => 'public_bug', deadline => '2010-01-01' }); + $bug = Bugzilla::Bug->create({ %field_values, alias => 'public_bug', deadline => '2010-01-01' }); + say 'Bug ' . $bug->id . ' (alias: public_bug) created'; } ########################################################################## # Create Classifications ########################################################################## -my @classifications = ({ name => "Class2_QA", + +my @classifications = ({ name => 'Class2_QA', description => "required by Selenium... DON'T DELETE" }, ); -print "creating classifications...\n"; +say 'creating classifications...'; for my $class (@classifications) { my $new_class = Bugzilla::Classification->new({ name => $class->{name} }); if (!$new_class) { $dbh->do('INSERT INTO classifications (name, description) VALUES (?, ?)', - undef, ( $class->{name}, $class->{description} )); + undef, ($class->{name}, $class->{description})); } } ########################################################################## # Create Products ########################################################################## + my @products = ( { product_name => 'QA-Selenium-TEST', description => "used by Selenium test.. DON'T DELETE", @@ -201,37 +216,32 @@ BEGIN milestones => ['QAMilestone'], defaultmilestone => '---', components => [ - { name => "QA-Selenium-TEST", + { name => 'QA-Selenium-TEST', description => "used by Selenium test.. DON'T DELETE", initialowner => $config->{QA_Selenium_TEST_user_login}, initialqacontact => $config->{QA_Selenium_TEST_user_login}, initial_cc => [$config->{QA_Selenium_TEST_user_login}], - } ], }, { product_name => 'Another Product', - description => - "Alternate product used by Selenium. Do not edit!", + description => 'Alternate product used by Selenium. Do not edit!', versions => ['unspecified', 'Another1', 'Another2'], milestones => ['AnotherMS1', 'AnotherMS2', 'Milestone'], defaultmilestone => '---', - components => [ - { name => "c1", - description => "c1", + { name => 'c1', + description => 'c1', initialowner => $config->{permanent_user}, initialqacontact => '', initial_cc => [], - }, - { name => "c2", - description => "c2", + { name => 'c2', + description => 'c2', initialowner => $config->{permanent_user}, initialqacontact => '', initial_cc => [], - }, ], }, @@ -244,12 +254,11 @@ BEGIN milestones => ['C2Mil'], defaultmilestone => '---', components => [ - { name => "Helium", - description => "Feel free to add bugs to me", + { name => 'Helium', + description => 'Feel free to add bugs to me', initialowner => $config->{permanent_user}, initialqacontact => '', initial_cc => [], - } ], }, @@ -260,7 +269,7 @@ BEGIN milestones => [], defaultmilestone => '---', components => [ - { name => "c1", + { name => 'c1', description => "Same name as Another Product's component", initialowner => $config->{QA_Selenium_TEST_user_login}, initialqacontact => '', @@ -275,8 +284,8 @@ BEGIN milestones => [], defaultmilestone => '---', components => [ - { name => "c1", - description => "Still same name as the Another component", + { name => 'c1', + description => 'Still same name as the Another component', initialowner => $config->{QA_Selenium_TEST_user_login}, initialqacontact => '', initial_cc => [], @@ -285,29 +294,26 @@ BEGIN }, ); -print "creating products...\n"; -for my $product (@products) { - my $new_product = - Bugzilla::Product->new({ name => $product->{product_name} }); +say 'creating products...'; +foreach my $product (@products) { + my $new_product = Bugzilla::Product->new({ name => $product->{product_name} }); if (!$new_product) { my $class_id = 1; if ($product->{classification}) { $class_id = Bugzilla::Classification->new({ name => $product->{classification} })->id; } $dbh->do('INSERT INTO products (name, description, classification_id) VALUES (?, ?, ?)', - undef, ( $product->{product_name}, $product->{description}, $class_id )); + undef, ($product->{product_name}, $product->{description}, $class_id)); - $new_product - = new Bugzilla::Product( { name => $product->{product_name} } ); + $new_product = Bugzilla::Product->new({ name => $product->{product_name} }); - $dbh->do( 'INSERT INTO milestones (product_id, value) VALUES (?, ?)', - undef, ( $new_product->id, $product->{defaultmilestone} ) ); + $dbh->do('INSERT INTO milestones (product_id, value) VALUES (?, ?)', + undef, ($new_product->id, $product->{defaultmilestone} )); # Now clear the internal list of accessible products. delete Bugzilla->user->{selectable_products}; - for my $component ( @{ $product->{components} } ) { - + foreach my $component (@{ $product->{components} }) { Bugzilla::Component->create( { name => $component->{name}, product => $new_product, @@ -315,24 +321,21 @@ BEGIN initialowner => $component->{initialowner}, initialqacontact => $component->{initialqacontact}, initial_cc => $component->{initial_cc}, - } ); } } foreach my $version (@{ $product->{versions} }) { - if (!new Bugzilla::Version({ name => $version, - product => $new_product })) - { - Bugzilla::Version->create({value => $version, product => $new_product}); + my $new_version = Bugzilla::Version->new({ name => $version, product => $new_product }); + if (!$new_version) { + Bugzilla::Version->create({ value => $version, product => $new_product }); } } foreach my $milestone (@{ $product->{milestones} }) { - if (!new Bugzilla::Milestone({ name => $milestone, - product => $new_product })) - { + my $new_milestone = Bugzilla::Milestone->new({ name => $milestone, product => $new_product }); + if (!$new_milestone) { # We don't use Bugzilla::Milestone->create because we want to # bypass security checks. $dbh->do('INSERT INTO milestones (product_id, value) VALUES (?,?)', @@ -344,12 +347,13 @@ BEGIN ########################################################################## # Create Groups ########################################################################## + # create Master group -my ( $group_name, $group_desc ) - = ( "Master", "Master Selenium Group DO NOT EDIT!" ); +my ($group_name, $group_desc) = ('Master', 'Master Selenium Group DO NOT EDIT!'); -print "creating groups...\n"; -if ( !Bugzilla::Group->new( { name => $group_name } ) ) { +say 'creating groups...'; +my $new_group = Bugzilla::Group->new({ name => $group_name }); +if (!$new_group) { my $group = Bugzilla::Group->create({ name => $group_name, description => $group_desc, isbuggroup => 1}); @@ -357,22 +361,23 @@ BEGIN $dbh->do('INSERT INTO group_control_map (group_id, product_id, entry, membercontrol, othercontrol, canedit) SELECT ?, products.id, 0, ?, ?, 0 FROM products', - undef, ( $group->id, CONTROLMAPSHOWN, CONTROLMAPSHOWN ) ); + undef, ($group->id, CONTROLMAPSHOWN, CONTROLMAPSHOWN)); } # create QA-Selenium-TEST group. Do not use Group->create() so that # the admin group doesn't inherit membership (yes, that's what we want!). -( $group_name, $group_desc ) - = ( "QA-Selenium-TEST", "used by Selenium test.. DON'T DELETE" ); +($group_name, $group_desc) = ('QA-Selenium-TEST', "used by Selenium test.. DON'T DELETE"); -if ( !Bugzilla::Group->new( { name => $group_name } ) ) { +$new_group = Bugzilla::Group->new({ name => $group_name }); +if (!$new_group) { $dbh->do('INSERT INTO groups (name, description, isbuggroup, isactive) - VALUES (?, ?, 1, 1)', undef, ( $group_name, $group_desc ) ); + VALUES (?, ?, 1, 1)', undef, ($group_name, $group_desc)); } ########################################################################## # Add Users to Groups ########################################################################## + my @users_groups = ( { user => $config->{QA_Selenium_TEST_user_login}, group => 'QA-Selenium-TEST' }, { user => $config->{tweakparams_user_login}, group => 'tweakparams' }, @@ -380,63 +385,54 @@ BEGIN { user => $config->{editbugs_user_login}, group => 'editbugs' }, ); -print "adding users to groups...\n"; -for my $user_group (@users_groups) { +say 'adding users to groups...'; +foreach my $user_group (@users_groups) { + my $group = Bugzilla::Group->new({ name => $user_group->{group} }); + my $user = Bugzilla::User->new({ name => $user_group->{user} }); - my $group = new Bugzilla::Group( { name => $user_group->{group} } ); - my $user = new Bugzilla::User( { name => $user_group->{user} } ); - - my $sth_add_mapping = $dbh->prepare( - qq{INSERT INTO user_group_map (user_id, group_id, isbless, grant_type) - VALUES (?, ?, ?, ?)}); + my $sth_add_mapping = + $dbh->prepare('INSERT INTO user_group_map (user_id, group_id, isbless, grant_type) + VALUES (?, ?, ?, ?)'); # Don't crash if the entry already exists. - eval { - $sth_add_mapping->execute( $user->id, $group->id, 0, GRANT_DIRECT ); - }; + eval { $sth_add_mapping->execute($user->id, $group->id, 0, GRANT_DIRECT); }; } ########################################################################## # Associate Products with groups ########################################################################## + # Associate the QA-Selenium-TEST group with the QA-Selenium-TEST. -my $created_group = new Bugzilla::Group( { name => 'QA-Selenium-TEST' } ); -my $secret_product = new Bugzilla::Product( { name => 'QA-Selenium-TEST' } ); -my $no_entry = new Bugzilla::Product({ name => 'QA Entry Only' }); -my $no_search = new Bugzilla::Product({ name => 'QA Search Only' }); +my $created_group = Bugzilla::Group->new({ name => 'QA-Selenium-TEST' }); +my $secret_product = Bugzilla::Product->new({ name => 'QA-Selenium-TEST' }); +my $no_entry = Bugzilla::Product->new({ name => 'QA Entry Only' }); +my $no_search = Bugzilla::Product->new({ name => 'QA Search Only' }); -print "restricting products to groups...\n"; +say 'restricting products to groups...'; # Don't crash if the entries already exist. my $sth = $dbh->prepare('INSERT INTO group_control_map (group_id, product_id, entry, membercontrol, othercontrol, canedit) VALUES (?, ?, ?, ?, ?, ?)'); -eval { - $sth->execute($created_group->id, $secret_product->id, 1, CONTROLMAPMANDATORY, - CONTROLMAPMANDATORY, 0); -}; -eval { - $sth->execute($created_group->id, $no_entry->id, 1, CONTROLMAPNA, CONTROLMAPNA, 0); -}; -eval { - $sth->execute($created_group->id, $no_search->id, 0, CONTROLMAPMANDATORY, - CONTROLMAPMANDATORY, 0); -}; +eval { $sth->execute($created_group->id, $secret_product->id, 1, CONTROLMAPMANDATORY, CONTROLMAPMANDATORY, 0); }; +eval { $sth->execute($created_group->id, $no_entry->id, 1, CONTROLMAPNA, CONTROLMAPNA, 0); }; +eval { $sth->execute($created_group->id, $no_search->id, 0, CONTROLMAPMANDATORY, CONTROLMAPMANDATORY, 0); }; ########################################################################## # Create flag types ########################################################################## + my @flagtypes = ( {name => 'spec_multi_flag', desc => 'Specifically requestable and multiplicable bug flag', is_requestable => 1, is_requesteeble => 1, is_multiplicable => 1, grant_group => 'editbugs', target_type => 'b', cc_list => '', inclusions => ['Another Product:c1']}, ); -print "creating flag types...\n"; +say 'creating flag types...'; foreach my $flag (@flagtypes) { # The name is not unique, even within a single product/component, so there is NO WAY # to know if the existing flag type is the one we want or not. # As our Selenium scripts would be confused anyway if there is already such a flag name, # we simply skip it and assume the existing flag type is the one we want. - next if new Bugzilla::FlagType({ name => $flag->{name} }); + next if Bugzilla::FlagType->new({ name => $flag->{name} }); my $grant_group_id = $flag->{grant_group} ? Bugzilla::Group->new({ name => $flag->{grant_group} })->id : undef; my $request_group_id = $flag->{request_group} ? Bugzilla::Group->new({ name => $flag->{request_group} })->id : undef; @@ -469,6 +465,7 @@ BEGIN ########################################################################## # Create custom fields ########################################################################## + my @fields = ( { name => 'cf_QA_status', description => 'QA Status', @@ -490,7 +487,7 @@ BEGIN }, ); -print "creating custom fields...\n"; +say 'creating custom fields...'; foreach my $f (@fields) { # Skip existing custom fields. next if Bugzilla::Field->new({ name => $f->{name} }); @@ -522,34 +519,49 @@ BEGIN write_params(); } +if (Bugzilla->params->{timetrackinggroup} ne 'editbugs') { + SetParam('timetrackinggroup', 'editbugs'); + write_params(); +} + ######################## # Create a Private Bug # ######################## my $test_user = Bugzilla::User->check($config->{QA_Selenium_TEST_user_login}); +$test_user->{'groups'} = [ + Bugzilla::Group->new({ name => 'editbugs' }), + Bugzilla::Group->new({ name => 'QA-Selenium-TEST' }) +]; # editbugs is needed for alias creation Bugzilla->set_user($test_user); -print "Creating private bug(s)...\n"; if (Bugzilla::Bug->new('private_bug')->{error}) { + say 'Creating private bug...'; my %priv_values = %field_values; $priv_values{alias} = 'private_bug'; $priv_values{product} = 'QA-Selenium-TEST'; $priv_values{component} = 'QA-Selenium-TEST'; my $bug = Bugzilla::Bug->create(\%priv_values); + say 'Bug ' . $bug->id . ' (alias: private_bug) created'; } ###################### # Create Attachments # ###################### -print "creating attachments...\n"; +say 'creating attachments...'; # We use the contents of this script as the attachment. open(my $attachment_fh, '<', __FILE__) or die __FILE__ . ": $!"; my $attachment_contents; -{ local $/; $attachment_contents = <$attachment_fh>; } +{ + local $/; + $attachment_contents = <$attachment_fh>; +} close($attachment_fh); + foreach my $alias (qw(public_bug private_bug)) { - my $bug = new Bugzilla::Bug($alias); + my $bug = Bugzilla::Bug->new($alias); + foreach my $is_private (0, 1) { Bugzilla::Attachment->create({ bug => $bug, @@ -573,9 +585,9 @@ BEGIN description => 'Created for Bugzilla QA Tests, Keyword 2' }, ); -print "creating keywords...\n"; +say 'creating keywords...'; foreach my $kw (@keywords) { - next if new Bugzilla::Keyword({ name => $kw->{name} }); + next if Bugzilla::Keyword->new({ name => $kw->{name} }); Bugzilla::Keyword->create($kw); } @@ -583,7 +595,7 @@ BEGIN # Install the QA extension # ############################ -print "copying the QA extension...\n"; +say 'copying the QA extension...'; my $output = `cp -R ../extensions/QA $conf_path/extensions/.`; print $output if $output; @@ -593,4 +605,4 @@ BEGIN print $output if $output; chdir($cwd); -print "installation and configuration complete!\n"; +say 'installation and configuration complete!'; diff --git a/config/selenium_test.conf b/config/selenium_test.conf index 8d1b8ad..c0b51da 100644 --- a/config/selenium_test.conf +++ b/config/selenium_test.conf @@ -9,21 +9,24 @@ 'host' => 'localhost', 'port' => 4444, 'browser_url' => 'http://localhost', - 'attachment_file' => '%TRAVIS_BUILD_DIR%/qa/config/patch.diff', + 'attachment_file' => '/home/bugzilla/devel/htdocs/bugzilla/qa/config/patch.diff', 'bugzilla_installation' => 'bugzilla', - 'bugzilla_path' => '%TRAVIS_BUILD_DIR%', + 'bugzilla_path' => '/home/bugzilla/devel/htdocs/bugzilla', 'admin_user_login' => 'admin@my.company', 'admin_user_passwd' => '******', 'admin_user_username' => 'admin', + 'admin_user_api_key' => 'zQ5TSBzq7tTZMtKYq9K1ZqJMjifKx3cPL7pIGk9Q', 'permanent_user' => 'permanent_user@my.company', 'unprivileged_user_login' => 'no-privs@my.company', 'unprivileged_user_passwd' => '******', 'unprivileged_user_username' => 'no-privs', 'unprivileged_user_login_truncated' => 'no-privs@my', + 'unprivileged_user_api_key' => 'zQ5TSBzqP4nrdBKYq9Re4qJrjifKx3cK07pIGk9Q', 'QA_Selenium_TEST_user_login' => 'QA-Selenium-TEST@my.company', 'QA_Selenium_TEST_user_passwd' => '******', 'editbugs_user_login' => 'editbugs@my.company', 'editbugs_user_passwd' => '******', + 'editbugs_user_api_key' => 'zQ5ewBzq3gTrdBKYq9K1ZqJMjifKx3cKleE6k9TQ', 'canconfirm_user_login' => 'canconfirm@my.company', 'canconfirm_user_passwd' => '******', 'tweakparams_user_login' => 'tweakparams@my.company', diff --git a/extensions/QA/Config.pm b/extensions/QA/Config.pm index 59799ec..b4f6bc9 100644 --- a/extensions/QA/Config.pm +++ b/extensions/QA/Config.pm @@ -7,7 +7,9 @@ package Bugzilla::Extension::QA; +use 5.10.1; use strict; +use warnings; use constant NAME => 'QA'; diff --git a/extensions/QA/Extension.pm b/extensions/QA/Extension.pm index b5f404d..6915a85 100644 --- a/extensions/QA/Extension.pm +++ b/extensions/QA/Extension.pm @@ -7,8 +7,11 @@ package Bugzilla::Extension::QA; +use 5.10.1; use strict; -use base qw(Bugzilla::Extension); +use warnings; + +use parent qw(Bugzilla::Extension); use Bugzilla::Extension::QA::Util; use Bugzilla::Constants; diff --git a/extensions/QA/lib/Util.pm b/extensions/QA/lib/Util.pm index 9bc2d8d..3b796ea 100644 --- a/extensions/QA/lib/Util.pm +++ b/extensions/QA/lib/Util.pm @@ -7,8 +7,11 @@ package Bugzilla::Extension::QA::Util; +use 5.10.1; use strict; -use base qw(Exporter); +use warnings; + +use parent qw(Exporter); our @EXPORT = qw( parse_output diff --git a/t/lib/QA/DB.pm b/t/lib/QA/DB.pm deleted file mode 100644 index b8bcc14..0000000 --- a/t/lib/QA/DB.pm +++ /dev/null @@ -1,85 +0,0 @@ -# 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 strict; -use warnings; - -package QA::DB; - -use fields qw( - _user - _password -); - -use constant MAX_RETRIES => 3; - -sub new { - my ($class, $params) = @_; - - my $driver = $params->{db_type}; - my $module = "QA/DB/$driver.pm"; - require $module; - - my $self = "QA::DB::$driver"->new(@_); - - $self->{_user} = $params->{user}; - $self->{_password} = $params->{password}; - - return $self; -} - -sub diff_schema { - my ($self, $from, $to) = @_; - my $from_dir = "schema-$from-sorted"; - my $to_dir = "schema-$to-sorted"; - $self->create_schema_map($from) if !-d $from_dir; - $self->create_schema_map($to) if !-d $to_dir; - return `diff -Nruw $from_dir $to_dir`; - File::Path::rmtree($to_dir); -} - -sub download_dump { - my ($self, $params) = @_; - my ($url, $name) = ($params->{url}, $params->{name}); - - # Download gzipped dump file - my $dump_file = "$name.sql.gz"; - my $full = "$url/$dump_file"; - print "Downloading $full...\n"; - my $success = 0; - my $tries = 0; - while (!$success && $tries < MAX_RETRIES) { - $tries++; - print "Retrying (Try $tries)..." if $tries > 1; - next if system("curl", "-o", $dump_file, $full) != 0; - $success = 1; - } - die "Error downloading dump file $dump_file" if !$success; - - # Download - my $md5sum_file = "$name.md5sum"; - $full = "$url/$md5sum_file"; - print "Downloading $full...\n"; - $success = 0; - $tries = 0; - while (!$success && $tries < MAX_RETRIES) { - $tries++; - print "Retrying (Try $tries)..." if $tries > 1; - next if system("curl", "-o", $md5sum_file, $full) != 0; - $success = 1; - } - die "Error downloading md5sum file $md5sum_file" if !$success; - - # Check for integrity of file - print "Verifying integrity of dump file...\n"; - my $rc = system("md5sum", "-c", $md5sum_file); - die "Error verifying integrity of dump file" if $rc; - - return $dump_file; -} - -1; diff --git a/t/lib/QA/DB/MySQL.pm b/t/lib/QA/DB/MySQL.pm deleted file mode 100644 index f622683..0000000 --- a/t/lib/QA/DB/MySQL.pm +++ /dev/null @@ -1,182 +0,0 @@ -# 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 strict; -use warnings; - -package QA::DB::MySQL; - -use DBI; -use File::Basename; -use File::Path; -use File::Temp; -use IPC::Cmd; - -use base qw(QA::DB); -use fields qw( - _mysql -); - -use constant MAX_RETRIES => 3; - -sub new { - my $class = shift; - my $params = shift; - my $self = {}; - bless($self, $class); - return $self; -} - -sub drop_db { - my ($self, $db) = @_; - my ($user, $pass) = ($self->{_user}, $self->{_password}); - print "Dropping $db...\n"; - system("mysql -u $user -p$pass -e 'DROP DATABASE $db'"); -} - -sub import_db { - my ($self, $file, $db) = @_; - my ($user, $pass) = ($self->{_user}, $self->{_password}); - print "Creating $db...\n"; - system("mysqladmin -u $user -p$pass create $db"); - print "Importing $file...\n"; - system("zcat $file | mysql -u $user -p$pass $db"); -} - -sub copy_db { - my ($self, $params_ref) = @_; - my %params = %$params_ref; - my ($from, $to, $url) = ($params{from}, $params{to}, $params{url}); - my ($user, $pass) = ($self->{_user}, $self->{_password}); - - # The mysqldump often fails, so we want to retry until it succeeds, up - # to a certain number of retries. - my $success = 0; - my $tries = 0; - my $mysql_cmd = "mysql -u $user -p$pass $to"; - while (!$success && $tries < MAX_RETRIES) { - $tries++; - print "Retrying (Try $tries)..." if $tries > 1; - - # Import the 'from' database directly into the 'to' if the from - # does not exist. First we download the appropriate dump file to import. - if (!$self->db_exists($from) && $url) { - my $dump_file = $self->download_dump({ name => $from, - url => $url }); - $self->drop_db($to) if $self->db_exists($to); - $self->import_db($dump_file, $to); - return; - } - - $self->drop_db($to) if $self->db_exists($to); - - my $dump_dir = File::Temp::tempdir(CLEANUP => 1); - chmod 0777, $dump_dir; - - print "Creating $to...\n"; - system("mysqladmin -u $user -p$pass create $to"); - print "Dumping $from..."; - my $start = time; - my $dump_command = "mysqldump --opt --single-transaction " . - "-u $user -p$pass $from --tab=$dump_dir"; - my ($ok, $err, $all, $stdout, $stderr) = IPC::Cmd::run(command => $dump_command); - my $seconds = time - $start; - print "($seconds seconds)\n"; - $success = $ok; - if (!$success) { - $params{overwrite} = 1; # So that we can repeat it. - sleep 3; # Wait a few seconds for any error to clear. - print join "", @$stderr; - next; - } - - # Locally, it's much faster to use LOAD DATA INFILE. We can't - # directly use mysqlimport because it doesn't have an option to - # ignore foreign keys. - print "Creating tables for $to...\n"; - system("mysqldump -u $user -p$pass $from --no_data | $mysql_cmd"); - my $commands = "SET foreign_key_checks = 0;\n"; - foreach my $file (glob "$dump_dir/*.txt") { - my $table = basename($file); - $table =~ s/\.txt$//; - $commands .= "LOAD DATA INFILE '$file' INTO TABLE $table CHARACTER SET binary;\n"; - } - print "Importing data from $from into $to..."; - my $import_start = time; - system("mysql", "-u", $user, "-p$pass", "-e $commands", $to); - my $import_time = time - $import_start; - print "($import_time seconds)\n"; - File::Path::rmtree($dump_dir); - } -} - -sub db_exists { - my ($self, $db) = @_; - my $sth = $self->_mysql->prepare('SHOW DATABASES LIKE ?'); - $sth->execute($db); - return $sth->fetchrow_array() ? 1 : 0; -} - -sub reset { - system("rm -rf schema-*sorted"); -} - -sub create_schema_map { - my ($self, $for_db) = @_; - my ($user, $pass) = ($self->{_user}, $self->{_password}); - - my $schema_dir = "schema-$for_db"; - my $sorted_dir = "$schema_dir-sorted"; - - # Create the directories - mkdir $schema_dir; - mkdir $sorted_dir; - - chdir $schema_dir; - - # Create the basic map - system("mysqldump --opt -u$user -p$pass --no-data -T. $for_db"); - # Remove the comments - system(q{sed -i 's/^--.*$//' *.sql}); - # Remove commas from ends of lines, because they can cause - # false positives when we check for schema differences - system(q{sed -i 's/,$//' *.sql}); - # Moving from PACK_KEYS to not having it is a schema - # change we don't care about. - system(q{sed -i 's/ PACK_KEYS=1//' *.sql}); - # Upgraded DBs have AUTO_INCREMENT in their CREATE TABLE, but new DBs - # don't. - system(q{perl -i -pe 's/ AUTO_INCREMENT=\d+//' *.sql}); - # XXX Ignore custom fields. This is somewhat of a hack. - system(q{perl -pe 's/^\s+`cf.*\n//' -i bugs.sql}); - system(q{rm -f cf_*.sql}); - system(q{rm -f bug_cf*.sql}); - # Create the sorted map - system("find . -name \\*.sql -exec sort \\{\\}" - . " -o ../$sorted_dir/\\{\\} \\;"); - - chdir '..'; - - File::Path::rmtree($schema_dir); - - return $sorted_dir; -} - -sub sql_random { return "RAND()"; } - -sub _mysql { - my $self = shift; - return $self->{_mysql} if $self->{_mysql}; - my $dsn = "DBI:mysql:"; - my $connection = DBI->connect($dsn, $self->{_user}, $self->{_password}, - { RaiseError => 1, AutoCommit => 1, PrintError => 0, TaintIn => 1, - ShowErrorStatement => 1, FetchHashKeyName => 'NAME_lc' }); - $self->{_mysql} = $connection; - return $self->{_mysql}; -} - -1; diff --git a/t/lib/QA/DB/Pg.pm b/t/lib/QA/DB/Pg.pm deleted file mode 100644 index f0a6ac1..0000000 --- a/t/lib/QA/DB/Pg.pm +++ /dev/null @@ -1,160 +0,0 @@ -# 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 strict; -use warnings; - -package QA::DB::Pg; - -use DBI; -use File::Path; -use POSIX; - -use base qw(QA::DB); -use fields qw( - _pg -); - -# PostgreSQL 8.3 and above won't let you connect to a SQL_ASCII -# database if you have a UTF-8 LC_CTYPE. It will allow connecting -# to any database from the C locale, though. -POSIX::setlocale(POSIX::LC_CTYPE, 'C'); - -sub new { - my $class = shift; - my $self = {}; - bless($self, $class); - return $self; -} - -sub drop_db { - my ($self, $db) = @_; - sleep 1; # Give Pg time to disconnect from anything it was connected to. - $self->_pg->do("DROP DATABASE $db"); -} - -sub copy_db { - my ($self, $params) = @_; - my ($from, $to) = ($params->{from}, $params->{to}); - my $from_host = $params->{from_host}; - my ($user, $pass) = ($self->{_user}, $self->{_password}); - - if ($self->db_exists($to)) { - if ($params->{overwrite}) { - $self->drop_db($to); - } - else { - die "You attempted to copy to '$to' but that database already" - . " exists."; - } - } - - if ($from_host) { - # A hack that only works on tinderbox.bugzilla.lan. - system("/usr/local/bin/pgclone $from $to"); - } - else { - $self->_pg->do("CREATE DATABASE $to TEMPLATE $from"); - } -} - -sub db_exists { - my ($self, $db) = @_; - return $self->_pg->selectrow_array( - "SELECT 1 FROM pg_stat_database WHERE datname = ?", undef, $db) ? 1 : 0; -} - -sub reset { - system("rm -rf schema-*sorted"); -} - -sub create_schema_map { - my ($self, $for_db) = @_; - my ($user, $pass) = ($self->{_user}, $self->{_password}); - - my $schema_dir = "schema-$for_db"; - my $sorted_dir = "$schema_dir-sorted"; - - # Create the directories - mkdir $schema_dir; - mkdir $sorted_dir; - - chdir $schema_dir || die "ERROR: Can't chdir to $schema_dir"; - - # Create the basic map - my $tables = $self->_tables($for_db); - foreach my $table (@$tables) { - system("pg_dump -Oxs -U $user -t $table $for_db > $table.sql"); - } - foreach my $file (glob '*.sql') { - _fix_sql_file($file); - } - # Create the sorted map - system("find . -name \\*.sql -exec sort \\{\\}" - . " -o ../$sorted_dir/\\{\\} \\;"); - - chdir '..'; - - File::Path::rmtree($schema_dir); - return $sorted_dir; -} - -sub _fix_sql_file { - my ($name) = @_; - open(my $fh, '<', $name) || die "$name: $!"; - my $content; - { local $/; $content = <$fh>; } - close $fh; - # Remove the comments - $content =~ s/^--.*$//gm; - # Remove commas from ends of lines, because they can cause - # false positives when we check for schema differences - $content =~ s/,$//gm; - # We don't really care about the DB encoding, since Bugzilla - # doesn't specify one on creation. - $content =~ s/^SET client_encoding.*$//gm; - # default_with_oids doesn't matter - $content =~ s/^SET default_with_oids.*$//gm; - # "integer DEFAULT nextval" is the same as serial, but in Pg 8.3, - # that's just represented as "integer" here. - $content =~ s/integer DEFAULT nextval\(\S+\)/integer/g; - # START WITH \d+ is some extra sequence stuff that shows up in populated - # DBs that doesn't show up in empty DBs. - $content =~ s/^\s+START WITH \d+$//gm; - # Remove all the lines that are just empty space. - $content =~ s/^\n//gm; - open(my $write_fh, '>', $name) || die "$name: $!"; - print $write_fh $content; - close $write_fh; -} - -sub sql_random { return "RANDOM()"; } - -sub _tables { - my ($self, $db_name) = @_; - my $dbh = $self->_pg($db_name); - my $table_sth = $dbh->table_info(undef, undef, undef, "TABLE"); - my $list = $dbh->selectcol_arrayref($table_sth, { Columns => [3] }); - # All PostgreSQL system tables start with "pg_" or "sql_" - @$list = grep(!/(^pg_)|(^sql_)/, @$list); - $dbh->disconnect; - return $list; -} - -sub _pg { - my ($self, $db_name) = @_; - return $self->{_pg} if ($self->{_pg} && !$db_name); - $db_name ||= 'postgres'; - my $dsn = "DBI:Pg:dbname=$db_name"; - my $connection = DBI->connect($dsn, $self->{_user}, $self->{_password}, - { RaiseError => 1, AutoCommit => 1, PrintError => 0, TaintIn => 1, - ShowErrorStatement => 1, FetchHashKeyName => 'NAME_lc' }); - ($self->{_pg} = $connection) if $db_name eq 'postgres'; - return $connection; -} - -1; diff --git a/t/lib/QA/DB/SQLite.pm b/t/lib/QA/DB/SQLite.pm deleted file mode 100644 index 9a29e83..0000000 --- a/t/lib/QA/DB/SQLite.pm +++ /dev/null @@ -1,74 +0,0 @@ -# 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 strict; -use warnings; - -package QA::DB::SQLite; - -use DBI; -use File::Basename; -use File::Path; -use File::Temp; -use IPC::Cmd; - -use base qw(QA::DB); - -our $DB_DIR = "data/db"; - -sub new { - my $class = shift; - my $params = shift; - my $self = {}; - bless($self, $class); - return $self; -} - -sub drop_db { - my ($self, $db) = @_; - print "Dropping $db...\n"; - system("rm", "-f", "$DB_DIR/$db"); -} - -sub copy_db { - my ($self, $params_ref) = @_; - my %params = %$params_ref; - my ($from, $to) = ($params{from}, $params{to}); - my $from_host = $params{from_host}; - - if ($self->db_exists($to)) { - if ($params{overwrite}) { - $self->drop_db($to); - } - else { - die "You attempted to copy to '$to' but that database already" - . " exists."; - } - } - - if ($from_host) { - system('scp', "$from_host:$from.sql", "$DB_DIR/$to.sql"); - system('sqlite3', "-init", "$DB_DIR/$to.sql", "$DB_DIR/$to"); - unlink "$DB_DIR/$to.sql"; - return; - } - - system('cp', '-a', "$DB_DIR/$from", "$DB_DIR/$to"); -} - - -sub db_exists { - my ($self, $db) = @_; - return -e "$DB_DIR/$db" ? 1 : 0; -} - -sub reset { -} - -sub sql_random { return "RANDOM()"; } - -1; diff --git a/t/lib/QA/REST.pm b/t/lib/QA/REST.pm new file mode 100644 index 0000000..56f27d5 --- /dev/null +++ b/t/lib/QA/REST.pm @@ -0,0 +1,54 @@ +package QA::REST; + +use 5.10.1; +use strict; +use warnings; +use autodie; + +use LWP::UserAgent; +use JSON; +use QA::Util; + +use parent qw(LWP::UserAgent Exporter); + +@QA::REST::EXPORT = qw( + MUST_FAIL + get_rest_client +); + +use constant MUST_FAIL => 1; + +sub get_rest_client { + my $rest_client = LWP::UserAgent->new( ssl_opts => { verify_hostname => 0 } ); + bless($rest_client, 'QA::REST'); + my $config = $rest_client->{bz_config} = get_config(); + $rest_client->{bz_url} = $config->{browser_url} . '/' . $config->{bugzilla_installation} . '/rest/'; + $rest_client->{bz_default_headers} = {'Accept' => 'application/json', 'Content-Type' => 'application/json'}; + return $rest_client; +} + +sub bz_config { return $_[0]->{bz_config}; } + +sub call { + my ($self, $method, $data, $http_verb, $expect_to_fail) = @_; + $http_verb = lc($http_verb || 'GET'); + $data //= {}; + + my %args = %{ $self->{bz_default_headers} }; + # We do not pass the API key in the URL, so that it's not logged by the web server. + if ($http_verb eq 'get' && $data->{api_key}) { + $args{'X-BUGZILLA-API-KEY'} = $data->{api_key}; + } + elsif ($http_verb ne 'get') { + $args{Content} = encode_json($data); + } + + my $response = $self->$http_verb($self->{bz_url} . $method, %args); + my $res = decode_json($response->decoded_content); + if ($response->is_success xor $expect_to_fail) { + return $res; + } + else { + die 'error ' . $res->{code} . ': ' . $res->{message} . "\n"; + } +} diff --git a/t/lib/QA/RPC.pm b/t/lib/QA/RPC.pm index 3d49ac0..6bf81bd 100644 --- a/t/lib/QA/RPC.pm +++ b/t/lib/QA/RPC.pm @@ -49,11 +49,6 @@ sub bz_log_in { 'User.login', { login => $username, password => $password }); cmp_ok($call->result->{id}, 'gt', 0, $self->TYPE . ": Logged in as $user"); $self->{_bz_credentials}->{token} = $call->result->{token}; - - # Save the cookies in the cookie file - $self->transport->cookie_jar->extract_cookies( - $self->transport->http_response); - $self->transport->cookie_jar->save; } sub bz_call_success { @@ -150,12 +145,10 @@ sub bz_create_test_bugs { my @summary_strings = _string_array(3); my $public_bug = create_bug_fields($config); - $public_bug->{alias} = random_string(20); $public_bug->{whiteboard} = join(' ', @whiteboard_strings); $public_bug->{summary} = join(' ', @summary_strings); my $private_bug = dclone($public_bug); - $private_bug->{alias} = random_string(20); if ($second_private) { $private_bug->{product} = 'QA-Selenium-TEST'; $private_bug->{component} = 'QA-Selenium-TEST'; diff --git a/t/lib/QA/RPC/JSONRPC.pm b/t/lib/QA/RPC/JSONRPC.pm index 2483ec6..212210a 100644 --- a/t/lib/QA/RPC/JSONRPC.pm +++ b/t/lib/QA/RPC/JSONRPC.pm @@ -101,7 +101,7 @@ sub _get { my $callback = $self->_bz_callback; if (defined $callback and $result->is_success) { my $content = $result->content; - $content =~ s/^\Q$callback(\E(.*)\)$/$1/s; + $content =~ s/^(?:\/\*\*\/)?\Q$callback(\E(.*)\)$/$1/s; $result->content($content); # We don't need this anymore, and we don't want it to affect # future calls. diff --git a/t/lib/QA/Util.pm b/t/lib/QA/Util.pm index 1a72a5f..60f7475 100644 --- a/t/lib/QA/Util.pm +++ b/t/lib/QA/Util.pm @@ -2,14 +2,15 @@ package QA::Util; +use 5.10.1; use strict; +use warnings; +use autodie; + use Data::Dumper; -use HTTP::Cookies; use Test::More; -use Test::WWW::Selenium; -use WWW::Selenium::Util qw(server_is_running); -use base qw(Exporter); +use parent qw(Exporter); @QA::Util::EXPORT = qw( trim url_quote @@ -31,6 +32,7 @@ use base qw(Exporter); get_selenium get_rpc_clients + get_config WAIT_TIME CHROME_MODE @@ -78,13 +80,17 @@ sub get_config { my $conf_file = CONF_FILE; my $config = do($conf_file) or die "can't read configuration '$conf_file': $!$@"; + return $config; } sub get_selenium { my $chrome_mode = shift; my $config = get_config(); - if (!server_is_running) { + require Test::WWW::Selenium; + require WWW::Selenium::Util; + + if (!WWW::Selenium::Util::server_is_running()) { die "Selenium Server isn't running!"; } @@ -100,24 +106,18 @@ sub get_selenium { sub get_xmlrpc_client { my $config = get_config(); - my $xmlrpc_url = $config->{browser_url} . "/" - . $config->{bugzilla_installation} . "/xmlrpc.cgi"; + my $xmlrpc_url = $config->{browser_url} . "/" . + $config->{bugzilla_installation} . "/xmlrpc.cgi"; require QA::RPC::XMLRPC; - # A temporary cookie jar that isn't saved after the script closes. - my $cookie_jar = new HTTP::Cookies(); - my $rpc = new QA::RPC::XMLRPC(proxy => $xmlrpc_url); - $rpc->transport->cookie_jar($cookie_jar); + my $rpc = QA::RPC::XMLRPC->new(proxy => $xmlrpc_url); return ($rpc, $config); } sub get_jsonrpc_client { my ($get_mode) = @_; require QA::RPC::JSONRPC; - # A temporary cookie jar that isn't saved after the script closes. - my $cookie_jar = new HTTP::Cookies(); - my $rpc = new QA::RPC::JSONRPC(); - $rpc->transport->cookie_jar($cookie_jar); + my $rpc = QA::RPC::JSONRPC->new(); # If we don't set a long timeout, then the Bug.add_comment test # where we add a too-large comment fails. $rpc->transport->timeout(180); @@ -172,7 +172,7 @@ sub file_bug_in_product { $sel->click_ok("link=New", undef, "Go create a new bug"); $sel->wait_for_page_to_load(WAIT_TIME); my $title = $sel->get_title(); - if ($title eq "Select Classification") { + if ($sel->is_text_present("Select Classification")) { ok(1, "More than one enterable classification available. Display them in a list"); $sel->click_ok("link=$classification", undef, "Choose $classification"); $sel->wait_for_page_to_load(WAIT_TIME); @@ -196,7 +196,7 @@ sub create_bug { $sel->click_ok('commit'); $sel->wait_for_page_to_load_ok(WAIT_TIME); my $bug_id = $sel->get_value('//input[@name="id" and @type="hidden"]'); - $sel->title_is("Bug $bug_id $ndash $bug_summary", "Bug $bug_id created with summary '$bug_summary'"); + $sel->title_like(qr/$bug_id $ndash( \(.*\))? $bug_summary/, "Bug $bug_id created with summary '$bug_summary'"); return $bug_id; } @@ -207,7 +207,7 @@ sub edit_bug { $sel->click_ok($btn_id); $sel->wait_for_page_to_load_ok(WAIT_TIME); - $sel->title_is("Bug $bug_id $ndash $bug_summary", "Changes submitted to bug $bug_id"); + $sel->title_is("$bug_id $ndash $bug_summary", "Changes submitted to bug $bug_id"); # If the web browser doesn't support history.ReplaceState or has it turned off, # "Bug XXX processed" is displayed instead (as in Bugzilla 4.0 and older). # $sel->title_is("Bug $bug_id processed", "Changes submitted to bug $bug_id"); @@ -216,11 +216,10 @@ sub edit_bug { sub edit_bug_and_return { my ($sel, $bug_id, $bug_summary, $options) = @_; my $ndash = NDASH; - edit_bug($sel, $bug_id, $bug_summary, $options); - $sel->click_ok("link=bug $bug_id"); + $sel->click_ok("//a[contains(\@href, 'show_bug.cgi?id=$bug_id')]"); $sel->wait_for_page_to_load_ok(WAIT_TIME); - $sel->title_is("Bug $bug_id $ndash $bug_summary", "Returning back to bug $bug_id"); + $sel->title_is("$bug_id $ndash $bug_summary", "Returning back to bug $bug_id"); } # Go to show_bug.cgi. @@ -232,7 +231,7 @@ sub go_to_bug { $sel->wait_for_page_to_load_ok(WAIT_TIME); my $bug_title = $sel->get_title(); utf8::encode($bug_title) if utf8::is_utf8($bug_title); - $sel->title_like(qr/^Bug $bug_id /, $bug_title); + $sel->title_like(qr/^$bug_id /, $bug_title); } # Go to admin.cgi. diff --git a/t/rest_bugzilla.t b/t/rest_bugzilla.t new file mode 100644 index 0000000..7b3d84d --- /dev/null +++ b/t/rest_bugzilla.t @@ -0,0 +1,52 @@ +####################################### +# Tests for REST calls in Bugzilla.pm # +####################################### + +use 5.10.1; +use strict; +use warnings; + +use lib qw(lib); + +use Test::More tests => 11; +use QA::REST; + +my $rest = get_rest_client(); +my $config = $rest->bz_config; + +my $version = $rest->call('version')->{version}; +ok($version, "GET /rest/version returns $version"); + +my $extensions = $rest->call('extensions')->{extensions}; +isa_ok($extensions, 'HASH', 'GET /rest/extensions'); +my @ext_names = sort keys %$extensions; +# There is always at least the QA extension enabled. +ok(scalar(@ext_names), scalar(@ext_names) . ' extension(s) found: ' . join(', ', @ext_names)); +ok($extensions->{QA}, 'The QA extension is enabled, with version ' . $extensions->{QA}->{version}); + +my $timezone = $rest->call('timezone')->{timezone}; +ok($timezone, "GET /rest/timezone retuns $timezone"); + +my $time = $rest->call('time'); +foreach my $type (qw(db_time web_time)) { + ok($time->{$type}, "GET /rest/time returns $type = " . $time->{$type}); +} + +# Logged-out users can only access the maintainer and requirelogin parameters. +my $params = $rest->call('parameters')->{parameters}; +my @param_names = sort keys %$params; +ok(@param_names == 2 && defined $params->{maintainer} && defined $params->{requirelogin}, + 'Only 2 parameters accessible to logged-out users: ' . join(', ', @param_names)); + +# Powerless users can access much more parameters. +$params = $rest->call('parameters', { api_key => $config->{unprivileged_user_api_key} })->{parameters}; +@param_names = sort keys %$params; +ok(@param_names > 2, scalar(@param_names) . ' parameters accessible to powerless users'); + +# Admins can access all parameters. +$params = $rest->call('parameters', { api_key => $config->{admin_user_api_key} })->{parameters}; +@param_names = sort keys %$params; +ok(@param_names > 2, scalar(@param_names) . ' parameters accessible to admins'); + +my $timestamp = $rest->call('last_audit_time')->{last_audit_time}; +ok($timestamp, "GET /rest/last_audit_time returns $timestamp"); diff --git a/t/rest_classification.t b/t/rest_classification.t new file mode 100644 index 0000000..e433334 --- /dev/null +++ b/t/rest_classification.t @@ -0,0 +1,53 @@ +############################################# +# Tests for REST calls in Classification.pm # +############################################# + +use 5.10.1; +use strict; +use warnings; + +use lib qw(lib); + +use Test::More tests => 7; +use QA::REST; + +my $rest = get_rest_client(); +my $config = $rest->bz_config; +my $args = { api_key => $config->{admin_user_api_key} }; + +my $params = $rest->call('parameters', $args)->{parameters}; +my $use_class = $params->{useclassification}; +ok(defined($use_class), 'Classifications are ' . ($use_class ? 'enabled' : 'disabled')); + +# Admins can always access classifications, even when they are disabled. +my $class = $rest->call('classification/1', $args)->{classifications}->[0]; +ok($class->{id}, "Admin found classification '" . $class->{name} . "' with the description '" . $class->{description} . "'"); +my @products = sort map { $_->{name} } @{ $class->{products} }; +ok(scalar(@products), scalar(@products) . ' product(s) found: ' . join(', ', @products)); + +$class = $rest->call('classification/Class2_QA', $args)->{classifications}->[0]; +ok($class->{id}, "Admin found classification '" . $class->{name} . "' with the description '" . $class->{description} . "'"); +@products = sort map { $_->{name} } @{ $class->{products} }; +ok(scalar(@products), scalar(@products) . ' product(s) found: ' . join(', ', @products)); + +if ($use_class) { + # When classifications are enabled, everybody can query classifications... + # ... including logged-out users. + $class = $rest->call('classification/1')->{classifications}->[0]; + ok($class->{id}, 'Logged-out users can access classification ' . $class->{name}); + # ... and non-admins. + $class = $rest->call('classification/1', { api_key => $config->{editbugs_user_api_key} })->{classifications}->[0]; + ok($class->{id}, 'Non-admins can access classification ' . $class->{name}); +} +else { + # When classifications are disabled, only users in the 'editclassifications' + # group can access this method... + # ... logged-out users get an error. + my $error = $rest->call('classification/1', undef, undef, MUST_FAIL); + ok($error->{error} && $error->{code} == 900, + 'Logged-out users cannot query classifications when disabled: ' . $error->{message}); + # ... as well as non-admins. + $error = $rest->call('classification/1', { api_key => $config->{editbugs_user_api_key} }, undef, MUST_FAIL); + ok($error->{error} && $error->{code} == 900, + 'Non-admins cannot query classifications when disabled: ' . $error->{message}); +} diff --git a/t/test_bug_edit.t b/t/test_bug_edit.t index 45ac3b1..2e2d49c 100644 --- a/t/test_bug_edit.t +++ b/t/test_bug_edit.t @@ -16,7 +16,7 @@ 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("link=Forget Search '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"); @@ -61,9 +61,9 @@ edit_bug($sel, $bug1_id, $bug_summary); # Now move the bug into another product, which has a mandatory group. -$sel->click_ok("link=bug $bug1_id"); +$sel->click_ok("link=$bug1_id"); $sel->wait_for_page_to_load_ok(WAIT_TIME); -$sel->title_like(qr/^Bug $bug1_id /); +$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"); @@ -130,7 +130,7 @@ 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("Access Denied"); +$sel->title_is("Bug Access Denied"); $sel->is_text_present_ok("You are not authorized to access bug #$bug1_id"); logout($sel); @@ -269,7 +269,7 @@ $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/Bug \d+ \S $bug_summary2/, "Bug created"); +$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); @@ -292,7 +292,7 @@ $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("link=Change Several Bugs at Once"); +$sel->click_ok("mass_change"); $sel->wait_for_page_to_load_ok(WAIT_TIME); $sel->title_is("Bug List"); $sel->click_ok("check_all"); @@ -303,9 +303,9 @@ $sel->click_ok("commit"); $sel->wait_for_page_to_load_ok(WAIT_TIME); $sel->title_is("Bugs processed"); -$sel->click_ok("link=bug $bug1_id"); +$sel->click_ok("link=$bug1_id"); $sel->wait_for_page_to_load_ok(WAIT_TIME); -$sel->title_like(qr/Bug $bug1_id /); +$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); @@ -333,7 +333,7 @@ if ($config->{test_extensions}) { $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("link=Change Several Bugs at Once"); + $sel->click_ok("mass_change"); $sel->wait_for_page_to_load_ok(WAIT_TIME); $sel->title_is("Bug List"); $sel->click_ok("check_all"); @@ -343,9 +343,9 @@ if ($config->{test_extensions}) { $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=bug $bug2_id"); + $sel->click_ok("link=$bug2_id"); $sel->wait_for_page_to_load_ok(WAIT_TIME); - $sel->title_like(qr/^Bug $bug2_id/); + $sel->title_like(qr/^$bug2_id/); $sel->selected_label_is("resolution", "MOVED"); $sel->is_text_present_ok("Bug moved to http://www.foo.com/."); @@ -376,9 +376,9 @@ foreach my $params (["no_token_mass_change", ""], ["invalid_token_mass_change", $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 $bug_id"); + $sel->click_ok("link=$bug_id"); $sel->wait_for_page_to_load_ok(WAIT_TIME); - $sel->title_like(qr/^Bug $bug_id /); + $sel->title_like(qr/^$bug_id /); $sel->is_text_present_ok($comment); next if $bug_id == $bug2_id; $sel->go_back_ok(); @@ -393,7 +393,7 @@ $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("link=Change Several Bugs at Once"); +$sel->click_ok("mass_change"); $sel->wait_for_page_to_load_ok(WAIT_TIME); $sel->title_is("Bug List"); $sel->click_ok("check_all"); @@ -408,7 +408,7 @@ $sel->title_is("Bugs processed"); $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("link=Forget Search '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"); diff --git a/t/test_create_user_accounts.t b/t/test_create_user_accounts.t index 918bfa0..0f87878 100644 --- a/t/test_create_user_accounts.t +++ b/t/test_create_user_accounts.t @@ -61,10 +61,20 @@ foreach my $account (@accounts) { # 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); diff --git a/t/test_custom_fields.t b/t/test_custom_fields.t index 46dd84e..c43ffe1 100644 --- a/t/test_custom_fields.t +++ b/t/test_custom_fields.t @@ -221,7 +221,7 @@ $sel->is_text_present_ok("Et de un"); # Now edit custom fields in mass changes. -$sel->click_ok("link=Change Several Bugs at Once"); +$sel->click_ok("mass_change"); $sel->wait_for_page_to_load_ok(WAIT_TIME); $sel->title_is("Bug List"); $sel->click_ok("check_all"); @@ -230,9 +230,9 @@ $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=bug $bug2_id"); +$sel->click_ok("link=$bug2_id"); $sel->wait_for_page_to_load_ok(WAIT_TIME); -$sel->title_like(qr/^Bug $bug2_id/); +$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"); diff --git a/t/test_default_groups.t b/t/test_default_groups.t deleted file mode 100644 index d2457b7..0000000 --- a/t/test_default_groups.t +++ /dev/null @@ -1,206 +0,0 @@ -use strict; -use warnings; -use lib qw(lib); - -use Test::More "no_plan"; - -use QA::Util; - -my ($sel, $config) = get_selenium(); - -# Turn on the makeproductgroups parameter. Create a new product and check that -# it has automatically a group created for it with the same name. - -log_in($sel, $config, 'admin'); -set_parameters($sel, { "Group Security" => {"makeproductgroups-on" => undef} }); -add_product($sel); -$sel->type_ok("product", "ready_to_die"); -$sel->type_ok("description", "will die"); -$sel->type_ok("component", "General"); -$sel->type_ok("comp_desc", "No specific role"); -$sel->type_ok("initialowner", $config->{permanent_user}); -$sel->click_ok('add-product'); -$sel->wait_for_page_to_load_ok(WAIT_TIME); -$sel->title_is("Product Created"); -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=ready_to_die"); -$sel->wait_for_page_to_load_ok(WAIT_TIME); -$sel->title_is("Change Group: ready_to_die"); -my $group_url = $sel->get_location(); -$group_url =~ /group=(\d+)/; -my $group1_id = $1; -$sel->value_is("desc", "Access to bugs in the ready_to_die product"); -my @groups = $sel->get_select_options("members_remove"); -ok((grep { $_ eq 'admin' } @groups), "'admin' inherits group membership"); -@groups = $sel->get_select_options("bless_from_remove"); -ok((grep { $_ eq 'admin' } @groups), "'admin' inherits can bless group membership"); -$sel->is_checked_ok("isactive"); - -# Check that the automatically created product group has the membercontrol -# for it set to Default and othercontrol set to NA. - -edit_product($sel, "ready_to_die"); -$sel->click_ok("link=Edit Group Access Controls:"); -$sel->wait_for_page_to_load_ok(WAIT_TIME); -$sel->title_is("Edit Group Controls for ready_to_die"); -$sel->value_is("entry_$group1_id", "off"); -$sel->value_is("canedit_$group1_id", "off"); -$sel->selected_label_is("membercontrol_$group1_id", "Default"); -$sel->selected_label_is("othercontrol_$group1_id", "NA"); - -edit_product($sel, "ready_to_die"); -$sel->go_back_ok(); -$sel->wait_for_page_to_load_ok(WAIT_TIME); -$sel->click_ok('//a[@href="editproducts.cgi?action=del&product=ready_to_die"]'); -$sel->wait_for_page_to_load_ok(WAIT_TIME); -$sel->title_is("Delete Product 'ready_to_die'"); -$sel->click_ok("delete"); -$sel->wait_for_page_to_load_ok(WAIT_TIME); -$sel->title_is("Product Deleted"); - -# The product has been deleted, but the group must survive. - -go_to_admin($sel); -$sel->click_ok("link=Groups"); -$sel->wait_for_page_to_load_ok(WAIT_TIME); -$sel->title_is("Edit Groups"); -$sel->is_text_present_ok("Access to bugs in the ready_to_die product"); - -# Create a new product. As the "ready_to_die" group already exists, -# a new "ready_to_die_" one must be created. - -add_product($sel); -$sel->type_ok("product", "ready_to_die"); -$sel->type_ok("description", "will die"); -$sel->type_ok("component", "General"); -$sel->type_ok("comp_desc", "No specific role"); -$sel->type_ok("initialowner", $config->{permanent_user}); -$sel->click_ok('add-product'); -$sel->wait_for_page_to_load_ok(WAIT_TIME); -$sel->title_is("Product Created"); - -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=ready_to_die_"); -$sel->wait_for_page_to_load_ok(WAIT_TIME); -$sel->title_is("Change Group: ready_to_die_"); -$group_url = $sel->get_location(); -$group_url =~ /group=(\d+)/; -my $group2_id = $1; -$sel->value_is("desc", "Access to bugs in the ready_to_die product"); -@groups = $sel->get_select_options("members_remove"); -ok((grep { $_ eq 'admin' } @groups), "'admin' inherits group membership"); -@groups = $sel->get_select_options("bless_from_remove"); -ok((grep { $_ eq 'admin' } @groups), "'admin' inherits can bless group membership"); -$sel->value_is("isactive", "on"); - -# Check group settings. The old 'ready_to_die' group has no relationship -# with this new product, despite its identical name. - -edit_product($sel, "ready_to_die"); -$sel->click_ok("link=Edit Group Access Controls:"); -$sel->wait_for_page_to_load_ok(WAIT_TIME); -$sel->title_is("Edit Group Controls for ready_to_die"); -$sel->value_is("entry_$group1_id", "off"); -$sel->value_is("entry_$group2_id", "off"); -$sel->value_is("canedit_$group1_id", "off"); -$sel->value_is("canedit_$group2_id", "off"); -$sel->selected_label_is("membercontrol_$group1_id", "NA"); -$sel->selected_label_is("othercontrol_$group1_id", "NA"); -$sel->selected_label_is("membercontrol_$group2_id", "Default"); -$sel->selected_label_is("othercontrol_$group2_id", "NA"); - -# Delete the ready_to_die_ group. It's bound to the ready_to_die product, -# so the deletion requires explicit agreement from the admin. - -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("//a[contains(\@href, 'editgroups.cgi?action=del&group=$group2_id')]"); -$sel->wait_for_page_to_load_ok(WAIT_TIME); -$sel->title_is("Delete group"); -$sel->is_text_present_ok("This group is tied to the following products"); -$sel->click_ok("delete"); -$sel->wait_for_page_to_load_ok(WAIT_TIME); -$sel->title_is("Cannot Delete Group"); -my $text = trim($sel->get_text("error_msg")); -ok($text =~ qr/All references to this group must be removed/, - "Group ready_to_die_ cannot be deleted as it is bound to a product"); -$sel->go_back_ok(); -$sel->wait_for_page_to_load_ok(WAIT_TIME); -$sel->title_is("Delete group"); -$sel->click_ok("unbind"); -$sel->click_ok("delete"); -$sel->wait_for_page_to_load_ok(WAIT_TIME); -$sel->title_is("Group Deleted"); -$text = trim($sel->get_text("message")); -ok($text =~ qr/The group ready_to_die_ has been deleted/, "Group ready_to_die_ has been deleted"); - -edit_product($sel, "ready_to_die"); -$sel->go_back_ok(); -$sel->wait_for_page_to_load_ok(WAIT_TIME); -$sel->click_ok('//a[@href="editproducts.cgi?action=del&product=ready_to_die"]'); -$sel->wait_for_page_to_load_ok(WAIT_TIME); -$sel->title_is("Delete Product 'ready_to_die'"); -$sel->click_ok("delete"); -$sel->wait_for_page_to_load_ok(WAIT_TIME); -$sel->title_is("Product Deleted"); - -# Reset the makeproductgroups parameter. Now creating a new product must -# not create a new group, nor bind any group with it. - -set_parameters($sel, { "Group Security" => {"makeproductgroups-off" => undef} }); -add_product($sel); -$sel->type_ok("product", "ready_to_die"); -$sel->type_ok("description", "will die"); -$sel->type_ok("component", "General"); -$sel->type_ok("comp_desc", "No specific role"); -$sel->type_ok("initialowner", $config->{permanent_user}); -$sel->click_ok('add-product'); -$sel->wait_for_page_to_load_ok(WAIT_TIME); -$sel->title_is("Product Created"); - -# Make sure that all group controls are set to NA for this product. - -edit_product($sel, "ready_to_die"); -$sel->title_is("Edit Product 'ready_to_die'"); -$sel->click_ok("link=Edit Group Access Controls:"); -$sel->wait_for_page_to_load_ok(WAIT_TIME); -$sel->title_is("Edit Group Controls for ready_to_die"); -$sel->value_is("entry_$group1_id", "off"); -$sel->value_is("canedit_$group1_id", "off"); -$sel->selected_label_is("membercontrol_$group1_id", "NA"); -$sel->selected_label_is("othercontrol_$group1_id", "NA"); - -# Delete remaining groups and products. - -go_to_admin($sel); -$sel->click_ok("link=Groups"); -$sel->wait_for_page_to_load_ok(WAIT_TIME); -$sel->title_is("Edit Groups"); -ok(!$sel->is_text_present('ready_to_die__'), 'No ready_to_die__ group created'); -$sel->click_ok("//a[contains(\@href, 'editgroups.cgi?action=del&group=$group1_id')]"); -$sel->wait_for_page_to_load_ok(WAIT_TIME); -$sel->title_is("Delete group"); -$sel->click_ok("delete"); -$sel->wait_for_page_to_load_ok(WAIT_TIME); -$sel->title_is("Group Deleted"); -$text = trim($sel->get_text("message")); -ok($text =~ /The group ready_to_die has been deleted/, "Group ready_to_die has been deleted"); - -edit_product($sel, "ready_to_die"); -$sel->go_back_ok(); -$sel->wait_for_page_to_load_ok(WAIT_TIME); -$sel->click_ok('//a[@href="editproducts.cgi?action=del&product=ready_to_die"]'); -$sel->wait_for_page_to_load_ok(WAIT_TIME); -$sel->title_is("Delete Product 'ready_to_die'"); -$sel->click_ok("delete"); -$sel->wait_for_page_to_load_ok(WAIT_TIME); -$sel->title_is("Product Deleted"); -logout($sel); diff --git a/t/test_email_preferences.t b/t/test_email_preferences.t index efdceca..a1d09a1 100644 --- a/t/test_email_preferences.t +++ b/t/test_email_preferences.t @@ -9,9 +9,14 @@ 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. @@ -47,10 +52,10 @@ my @email_normal = ($config->{editbugs_user_login}); log_in($sel, $config, 'admin'); $sel->click_ok("link=Preferences"); $sel->wait_for_page_to_load_ok(WAIT_TIME); -$sel->title_is("User Preferences"); -$sel->click_ok("link=Email Preferences"); +$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 Preferences"); +$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'); @@ -121,7 +126,7 @@ $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 preferences have been saved."); +$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 @@ -139,11 +144,11 @@ logout($sel); log_in($sel, $config, 'editbugs'); $sel->click_ok("link=Preferences"); $sel->wait_for_page_to_load(WAIT_TIME); -$sel->title_is("User Preferences"); -$sel->click_ok("link=Email Preferences"); +$sel->title_is("General Preferences"); +$sel->click_ok("link=Email Notifications"); $sel->wait_for_page_to_load(WAIT_TIME); -$sel->title_is("User Preferences"); -$sel->is_text_present_ok("Email Preferences"); +$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'); @@ -211,22 +216,19 @@ $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 preferences have been saved."); +$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 Preferences", "Enter bug description"); +$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); -my @email_sentto = get_email_sentto($sel); -is_deeply(\@email_both, \@email_sentto, "Admin and normal user got bugmail"); -my @email_excluded = get_email_excluded($sel); -ok($email_excluded[0] eq "no one", "Nobody excluded from bugmail"); +verify_bugmail_recipients($sel, RCPT_BOTH); # Make normal user changes (first pass) # @@ -235,35 +237,23 @@ go_to_bug($sel, $bug1_id); $sel->select_ok("bug_severity", "label=blocker"); $sel->selected_label_is("bug_severity", "blocker"); edit_bug($sel, $bug1_id, $bug_summary); -@email_sentto = get_email_sentto($sel); -is_deeply(\@email_normal, \@email_sentto, "Normal user got bugmail"); -@email_excluded = get_email_excluded($sel); -is_deeply(\@email_admin, \@email_excluded, "Admin excluded from bugmail"); +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); -@email_sentto = get_email_sentto($sel); -ok($email_sentto[0] eq "no one", "No bugmail sent"); -@email_excluded = get_email_excluded($sel); -is_deeply(\@email_both, \@email_excluded, "Admin and normal user excluded from bugmail"); +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); -@email_sentto = get_email_sentto($sel); -is_deeply(\@email_admin, \@email_sentto, "Admin got bugmail"); -@email_excluded = get_email_excluded($sel); -is_deeply(\@email_normal, \@email_excluded, "Normal user excluded from bugmail"); +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); -@email_sentto = get_email_sentto($sel); -ok($email_sentto[0] eq "no one", "No bugmail sent"); -@email_excluded = get_email_excluded($sel); -is_deeply(\@email_both, \@email_excluded, "Admin and normal user excluded from bugmail"); +verify_bugmail_recipients($sel, RCPT_NONE); # Make admin changes # @@ -274,52 +264,34 @@ go_to_bug($sel, $bug1_id); $sel->select_ok("bug_severity", "label=trivial"); $sel->selected_label_is("bug_severity", "trivial"); edit_bug($sel, $bug1_id, $bug_summary); -@email_sentto = get_email_sentto($sel); -is_deeply(\@email_normal, \@email_sentto, "Normal user got bugmail"); -@email_excluded = get_email_excluded($sel); -is_deeply(\@email_admin, \@email_excluded, "Admin excluded from bugmail"); +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); -@email_sentto = get_email_sentto($sel); -is_deeply(\@email_normal, \@email_sentto, "Normal user got bugmail"); -@email_excluded = get_email_excluded($sel); -is_deeply(\@email_admin, \@email_excluded, "Admin excluded from bugmail"); +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); -@email_sentto = get_email_sentto($sel); -is_deeply(\@email_both, \@email_sentto, "Admin and normal user got bugmail"); -@email_excluded = get_email_excluded($sel); -ok($email_excluded[0] eq "no one", "Nobody excluded from bugmail"); +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); -@email_sentto = get_email_sentto($sel); -is_deeply(\@email_both, \@email_sentto, "Admin and normal user got bugmail"); -@email_excluded = get_email_excluded($sel); -ok($email_excluded[0] eq "no one", "Nobody excluded from bugmail"); +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); -@email_sentto = get_email_sentto($sel); -is_deeply(\@email_admin, \@email_sentto, "Admin got bugmail"); -@email_excluded = get_email_excluded($sel); -is_deeply(\@email_normal, \@email_excluded, "Normal user excluded from bugmail"); +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); -@email_sentto = get_email_sentto($sel); -is_deeply(\@email_admin, \@email_sentto, "Admin got bugmail"); -@email_excluded = get_email_excluded($sel); -is_deeply(\@email_normal, \@email_excluded, "Normal user excluded from bugmail"); +verify_bugmail_recipients($sel, RCPT_ADMIN); # Make normal user changes (second pass) # @@ -330,41 +302,26 @@ go_to_bug($sel, $bug1_id); $sel->select_ok("bug_severity", "label=normal"); $sel->selected_label_is("bug_severity", "normal"); edit_bug($sel, $bug1_id, $bug_summary); -@email_sentto = get_email_sentto($sel); -is_deeply(\@email_both, \@email_sentto, "Admin and normal user got bugmail"); -@email_excluded = get_email_excluded($sel); -ok($email_excluded[0] eq "no one", "Nobody excluded from bugmail"); +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); -@email_sentto = get_email_sentto($sel); -is_deeply(\@email_admin, \@email_sentto, "Admin got bugmail"); -@email_excluded = get_email_excluded($sel); -is_deeply(\@email_normal, \@email_excluded, "Normal user excluded from bugmail"); +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); -@email_sentto = get_email_sentto($sel); -is_deeply(\@email_admin, \@email_sentto, "Admin got bugmail"); -@email_excluded = get_email_excluded($sel); -is_deeply(\@email_normal, \@email_excluded, "Normal user excluded from bugmail"); +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); -@email_sentto = get_email_sentto($sel); -ok($email_sentto[0] eq "no one", "No bugmail sent"); -@email_excluded = get_email_excluded($sel); -is_deeply(\@email_both, \@email_excluded, "Admin and normal user excluded from bugmail"); +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); -@email_sentto = get_email_sentto($sel); -ok($email_sentto[0] eq "no one", "No bugmail sent"); -@email_excluded = get_email_excluded($sel); -is_deeply(\@email_both, \@email_excluded, "Admin and normal user excluded from bugmail"); +verify_bugmail_recipients($sel, RCPT_NONE); logout($sel); # Set "After changing a bug" default preference back to "Do Nothing". @@ -380,14 +337,44 @@ $sel->title_is("Default Preferences"); logout($sel); # Help functions -sub get_email_sentto { - my ($sel) = @_; - return sort split(/, /, $sel->get_text("//dt[text()='Email sent to:']/following-sibling::dd")); -} +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; + } -sub get_email_excluded { - my ($sel) = @_; - return sort split(/, /, $sel->get_text("//dt[text()='Excluding:']/following-sibling::dd")); + # 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 { diff --git a/t/test_flags.t b/t/test_flags.t index e39a8b5..e3f3045 100644 --- a/t/test_flags.t +++ b/t/test_flags.t @@ -251,7 +251,7 @@ $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/^Bug $bug1_id /); +$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); @@ -329,7 +329,7 @@ my $attachment3_id = $1; $sel->click_ok("link=bug $bug1_id"); $sel->wait_for_page_to_load_ok(WAIT_TIME); -$sel->title_like(qr/^Bug $bug1_id /); +$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+"); @@ -366,15 +366,15 @@ ok(grep($_ eq '?', @flag_states), "Flag state '?' available"); $sel->click_ok("//a[\@href='attachment.cgi?id=$attachment2_id&action=edit']"); $sel->wait_for_page_to_load_ok(WAIT_TIME); -$sel->title_is("Attachment $attachment2_id Details for Bug $bug1_id"); -ok(!$sel->is_element_present('//select[@title="attachmentflag2"]'), +$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("link=Bug $bug1_id"); +$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/^Bug $bug1_id/); +$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"); @@ -402,7 +402,7 @@ 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_is("Attachment $attachment3_id Details for Bug $bug1_id"); +$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"}); diff --git a/t/test_groups.t b/t/test_groups.t index 3fd4062..d695ba0 100644 --- a/t/test_groups.t +++ b/t/test_groups.t @@ -145,18 +145,18 @@ ok(!$sel->is_element_present("b$bug2_id"), "Bug $bug2_id NOT restricted to the b # Make the Selenium-test group mandatory for TestProduct. edit_product($sel, "TestProduct"); -$sel->is_text_present_ok("Selenium-test: Shown/Mandatory"); +$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("the group is newly mandatory and will be added"); +$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\W+mandatory for this product'); +$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. @@ -253,7 +253,7 @@ $sel->is_element_present_ok("b$bug4_id", undef, "Bug $bug4_id restricted to the # 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->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"); @@ -263,7 +263,7 @@ $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("the group is no longer applicable and will be removed"); +$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 @@ -333,7 +333,7 @@ $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_is("Delete group"); +$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"); @@ -361,7 +361,7 @@ $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("link=Forget Search 'Selenium bugs'"); +$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."); diff --git a/t/test_keywords.t b/t/test_keywords.t index 65a0871..171ea50 100644 --- a/t/test_keywords.t +++ b/t/test_keywords.t @@ -147,8 +147,8 @@ $sel->is_text_present_ok("2 bugs found"); $sel->click_ok("link=$bug_summary"); $sel->wait_for_page_to_load(WAIT_TIME); -$sel->title_like(qr/^Bug $bug1_id /); -$sel->click_ok("link=Keywords"); +$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"); diff --git a/t/test_login.t b/t/test_login.t index c372be1..43f849d 100644 --- a/t/test_login.t +++ b/t/test_login.t @@ -23,5 +23,5 @@ $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 Username Or Password"); -$sel->is_text_present_ok("The username or password you entered is not valid."); +$sel->title_is("Invalid Login Or Password"); +$sel->is_text_present_ok("The login or password you entered is not valid."); diff --git a/t/test_milestones.t b/t/test_milestones.t index 322fefd..ceb3e13 100644 --- a/t/test_milestones.t +++ b/t/test_milestones.t @@ -8,12 +8,11 @@ use QA::Util; my ($sel, $config) = get_selenium(); -# 1st step: turn on usetargetmilestone, musthavemilestoneonaccept and letsubmitterchoosemilestone. +# 1st step: turn on usetargetmilestone and letsubmitterchoosemilestone. log_in($sel, $config, 'admin'); set_parameters($sel, {'Bug Fields' => {'usetargetmilestone-on' => undef}, - 'Bug Change Policies' => {'musthavemilestoneonaccept-on' => undef, - 'letsubmitterchoosemilestone-on' => undef}, + 'Bug Change Policies' => {'letsubmitterchoosemilestone-on' => undef}, } ); @@ -45,15 +44,10 @@ $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 (test musthavemilestoneonaccept ON). +# 4th step: edit the bug -$sel->select_ok("bug_status", "label=IN_PROGRESS", "Change bug status to IN_PROGRESS"); -$sel->click_ok("commit", undef, "Save changes"); -$sel->wait_for_page_to_load(WAIT_TIME); -$sel->title_is("Milestone Required", "Change rejected: musthavemilestoneonaccept is on but the milestone selected is the default one"); -$sel->is_text_present_ok("You must select a target milestone", undef, "Display error message"); -# We cannot use go_back_ok() because we just left post_bug.cgi where data has been submitted using POST. 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); @@ -65,10 +59,10 @@ $sel->selected_label_is("component", "TestComponent", "Component already selecte $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 'musthavemilestoneonaccept'"); +$sel->type_ok("comment", "Created by Selenium to test milestone support"); my $bug2_id = create_bug($sel, $bug_summary2); -# 6th step: edit the bug (test musthavemilestoneonaccept ON). +# 6th step: edit the bug $sel->select_ok("bug_status", "label=IN_PROGRESS"); edit_bug($sel, $bug2_id, $bug_summary2); @@ -136,16 +130,10 @@ $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 'musthavemilestoneonaccept'"); +$sel->type_ok("comment", "Created by Selenium to test milestone support"); my $bug3_id = create_bug($sel, $bug_summary3); -# 10th step: musthavemilestoneonaccept must have no effect as there is -# no other milestone available besides the default one. - $sel->select_ok("bug_status", "label=IN_PROGRESS"); edit_bug($sel, $bug3_id, $bug_summary3); -# 11th step: turn musthavemilestoneonaccept back to OFF. - -set_parameters($sel, {'Bug Change Policies' => {'musthavemilestoneonaccept-off' => undef}}); logout($sel); diff --git a/t/test_private_attachments.t b/t/test_private_attachments.t index 09ff01f..e1d2414 100644 --- a/t/test_private_attachments.t +++ b/t/test_private_attachments.t @@ -75,7 +75,7 @@ foreach my $user ('', 'unprivileged') { $sel->click_ok('//a[@href="attachment.cgi?id=' . $attachment1_id . '&action=edit"]'); $sel->wait_for_page_to_load_ok(WAIT_TIME); -$sel->title_is("Attachment $attachment1_id Details for Bug $bug1_id"); +$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"}); @@ -107,7 +107,7 @@ 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_is("Attachment $attachment2_id Details for Bug $bug1_id"); +$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"}); @@ -143,7 +143,7 @@ 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_is("Attachment $attachment2_id Details for Bug $bug1_id"); +$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"); diff --git a/t/test_qa_contact.t b/t/test_qa_contact.t index 10223f3..b940957 100644 --- a/t/test_qa_contact.t +++ b/t/test_qa_contact.t @@ -15,7 +15,7 @@ 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("link=Forget Search '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."); @@ -73,7 +73,7 @@ $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/^Bug $bug1_id /); +$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); @@ -84,7 +84,7 @@ logout($sel); $sel->type_ok("quicksearch_top", $bug1_id); $sel->click_ok("find_top"); $sel->wait_for_page_to_load_ok(WAIT_TIME); -$sel->title_is("Access Denied"); +$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 @@ -94,12 +94,12 @@ $sel->is_text_present_ok("You are not authorized to access bug"); $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->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("Access Denied"); +$sel->title_is("Bug Access Denied"); $sel->is_text_present_ok("You are not authorized to access bug"); logout($sel); @@ -115,11 +115,11 @@ logout($sel); log_in($sel, $config, 'unprivileged'); $sel->click_ok("link=Preferences"); $sel->wait_for_page_to_load_ok(WAIT_TIME); -$sel->title_is("User Preferences"); +$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("User Preferences"); +$sel->title_is("General Preferences"); open_advanced_search_page($sel); $sel->remove_all_selections_ok("product"); @@ -136,7 +136,7 @@ $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/Bug $bug1_id /); +$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"); @@ -146,7 +146,9 @@ edit_bug($sel, $bug1_id, $bug_summary); # with the bug. He can no longer see it. $sel->is_text_present_ok("(list of e-mails not available)"); -$sel->click_ok("link=bug $bug1_id"); +$sel->click_ok("link=$bug1_id"); $sel->wait_for_page_to_load_ok(WAIT_TIME); -$sel->title_is("Access Denied"); +$sel->title_is("Bug Access Denied"); logout($sel); + +$sel->stop(); diff --git a/t/test_saved_searches.t b/t/test_saved_searches.t index b1676e5..db677ec 100644 --- a/t/test_saved_searches.t +++ b/t/test_saved_searches.t @@ -13,10 +13,10 @@ my ($sel, $config) = get_selenium(); log_in($sel, $config, 'QA_Selenium_TEST'); $sel->click_ok("link=Preferences"); $sel->wait_for_page_to_load_ok(WAIT_TIME); -$sel->title_is("User Preferences"); +$sel->title_is("General Preferences"); $sel->click_ok("link=Saved Searches"); $sel->wait_for_page_to_load_ok(WAIT_TIME); -$sel->title_is("User Preferences"); +$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"). @@ -47,17 +47,17 @@ $sel->title_is("Bug List: SavedSearchTEST1"); $sel->click_ok("link=Preferences"); $sel->wait_for_page_to_load_ok(WAIT_TIME); -$sel->title_is("User Preferences"); +$sel->title_is("General Preferences"); $sel->click_ok("link=Saved Searches"); $sel->wait_for_page_to_load_ok(WAIT_TIME); -$sel->title_is("User Preferences"); +$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("User Preferences"); +$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"); @@ -84,22 +84,22 @@ ok($text =~ /Your search named SavedSearchTEST1 has been updated./, "Saved searc $sel->click_ok("link=Preferences"); $sel->wait_for_page_to_load_ok(WAIT_TIME); -$sel->title_is("User Preferences"); +$sel->title_is("General Preferences"); $sel->click_ok("link=Saved Searches"); $sel->wait_for_page_to_load_ok(WAIT_TIME); -$sel->title_is("User Preferences"); +$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("link=Edit Search"); +$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("link=Forget Search 'SavedSearchTEST1'"); +$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")); diff --git a/t/test_search.t b/t/test_search.t index 75dae60..c188580 100644 --- a/t/test_search.t +++ b/t/test_search.t @@ -33,7 +33,7 @@ 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("editme_action"); +$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...."); diff --git a/t/test_security.t b/t/test_security.t index b0cd84f..b9036d4 100644 --- a/t/test_security.t +++ b/t/test_security.t @@ -46,7 +46,7 @@ $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_is("Attachment $attach1_id Details for Bug $bug1_id"); +$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"}); @@ -61,7 +61,7 @@ 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/^Bug $bug1_id /); +$sel->title_like(qr/^$bug1_id /); # Alternate host for attachments; no cookie should be accessible. @@ -78,7 +78,7 @@ 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/^Bug $bug1_id /); +$sel->title_like(qr/^$bug1_id /); set_parameters($sel, { "Attachments" => {"reset-attachment_base" => undef} }); @@ -88,20 +88,20 @@ set_parameters($sel, { "Attachments" => {"reset-attachment_base" => undef} }); $sel->click_ok("link=Preferences"); $sel->wait_for_page_to_load_ok(WAIT_TIME); -$sel->title_is("User Preferences"); +$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("User Preferences"); +$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("User Preferences"); +$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. @@ -184,5 +184,5 @@ $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/Bug $bug1_id /); +$sel->title_like(qr/$bug1_id /); logout($sel); diff --git a/t/test_shared_searches.t b/t/test_shared_searches.t index 7d05801..04f25f5 100644 --- a/t/test_shared_searches.t +++ b/t/test_shared_searches.t @@ -31,10 +31,10 @@ ok($text =~ /OK, you have a new search named Shared Selenium buglist./, "New sea $sel->click_ok("link=Preferences"); $sel->wait_for_page_to_load_ok(WAIT_TIME); -$sel->title_is("User Preferences"); +$sel->title_is("General Preferences"); $sel->click_ok("link=Saved Searches"); $sel->wait_for_page_to_load_ok(WAIT_TIME); -$sel->title_is("User Preferences"); +$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; @@ -47,7 +47,7 @@ ok(!$sel->is_checked("force_$saved_search1_id"), "Shared search not displayed in $sel->click_ok("force_$saved_search1_id"); $sel->click_ok("update"); $sel->wait_for_page_to_load_ok(WAIT_TIME); -$sel->title_is("User Preferences"); +$sel->title_is("Saved Searches"); logout($sel); # Log in as the "canconfirm" user. The search shared by the admin must appear @@ -59,16 +59,16 @@ $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_text_present("Forget Search 'Shared Selenium buglist'"), "'Forget...' link not available"); +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("User Preferences"); +$sel->title_is("General Preferences"); $sel->click_ok("link=Saved Searches"); $sel->wait_for_page_to_load_ok(WAIT_TIME); -$sel->title_is("User Preferences"); +$sel->title_is("Saved Searches"); $sel->is_text_present_ok($config->{admin_user_login}); # Remove the shared search from your footer. @@ -77,11 +77,11 @@ $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("User Preferences"); +$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("User Preferences"); +$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. @@ -99,10 +99,10 @@ ok($text =~ /OK, you have a new search named helpwanted./, "New search named hel $sel->click_ok("link=Preferences"); $sel->wait_for_page_to_load_ok(WAIT_TIME); -$sel->title_is("User Preferences"); +$sel->title_is("General Preferences"); $sel->click_ok("link=Saved Searches"); $sel->wait_for_page_to_load_ok(WAIT_TIME); -$sel->title_is("User Preferences"); +$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; @@ -111,7 +111,7 @@ $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("User Preferences"); +$sel->title_is("Saved Searches"); logout($sel); # Log in as admin again. The other user is not a blesser for the 'canconfirm' @@ -122,10 +122,10 @@ 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("User Preferences"); +$sel->title_is("General Preferences"); $sel->click_ok("link=Saved Searches"); $sel->wait_for_page_to_load_ok(WAIT_TIME); -$sel->title_is("User Preferences"); +$sel->title_is("Saved Searches"); $sel->is_text_present_ok("helpwanted"); $sel->is_text_present_ok($config->{canconfirm_user_login}); @@ -133,7 +133,7 @@ ok(!$sel->is_checked("link_in_footer_$saved_search2_id"), "Shared query availabl $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("User Preferences"); +$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); @@ -143,10 +143,10 @@ $sel->title_is("Bug List: helpwanted"); $sel->click_ok("link=Preferences"); $sel->wait_for_page_to_load_ok(WAIT_TIME); -$sel->title_is("User Preferences"); +$sel->title_is("General Preferences"); $sel->click_ok("link=Saved Searches"); $sel->wait_for_page_to_load_ok(WAIT_TIME); -$sel->title_is("User Preferences"); +$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"); @@ -163,10 +163,10 @@ 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("User Preferences"); +$sel->title_is("General Preferences"); $sel->click_ok("link=Saved Searches"); $sel->wait_for_page_to_load_ok(WAIT_TIME); -$sel->title_is("User Preferences"); +$sel->title_is("Saved Searches"); ok(!$sel->is_text_present("helpwanted"), "The 'helpwanted' query is not shared with this user"); logout($sel); @@ -175,10 +175,10 @@ logout($sel); log_in($sel, $config, 'canconfirm'); $sel->click_ok("link=Preferences"); $sel->wait_for_page_to_load_ok(WAIT_TIME); -$sel->title_is("User Preferences"); +$sel->title_is("General Preferences"); $sel->click_ok("link=Saved Searches"); $sel->wait_for_page_to_load_ok(WAIT_TIME); -$sel->title_is("User Preferences"); +$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"); diff --git a/t/test_show_all_products.t b/t/test_show_all_products.t index 44a3f0a..306f822 100644 --- a/t/test_show_all_products.t +++ b/t/test_show_all_products.t @@ -20,12 +20,12 @@ set_parameters($sel, { "Bug Fields" => {"useclassification-on" => undef} }); $sel->click_ok("link=New"); $sel->wait_for_page_to_load_ok(WAIT_TIME); -$sel->title_is("Select Classification"); +$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->title_is("Enter Bug"); +$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); @@ -35,14 +35,12 @@ logout($sel); log_in($sel, $config, 'QA_Selenium_TEST'); $sel->click_ok("link=New"); $sel->wait_for_page_to_load_ok(WAIT_TIME); -$sel->title_is("Select Classification"); +$sel->is_text_present_ok("Select Classification"); $sel->click_ok("link=All"); $sel->wait_for_page_to_load_ok(WAIT_TIME); -$sel->title_is("Enter Bug"); +$sel->is_text_present_ok("Select Product"); $sel->is_text_present_ok("QA-Selenium-TEST"); -# For some unknown reason, Selenium doesn't like hyphens in links. -# $sel->click_ok("link=QA-Selenium-TEST"); -$sel->click_ok('//a[contains(@href, "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/t/test_status_whiteboard.t b/t/test_status_whiteboard.t index 85550b2..7503b74 100644 --- a/t/test_status_whiteboard.t +++ b/t/test_status_whiteboard.t @@ -88,7 +88,7 @@ $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("link=Change Several Bugs at Once"); +$sel->click_ok("mass_change"); $sel->wait_for_page_to_load_ok(WAIT_TIME); $sel->title_is("Bug List"); $sel->click_ok("check_all"); @@ -101,7 +101,7 @@ $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("link=Forget Search 'sw-x77v'"); +$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."); diff --git a/t/test_strict_isolation.t b/t/test_strict_isolation.t index 20198a9..a7dbda6 100644 --- a/t/test_strict_isolation.t +++ b/t/test_strict_isolation.t @@ -62,7 +62,7 @@ $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/^Bug $bug1_id /); +$sel->title_like(qr/^$bug1_id /); $sel->click_ok("cc_edit_area_showhide"); $sel->type_ok("newcc", $qa_user); $sel->click_ok("commit"); diff --git a/t/test_sudo_sessions.t b/t/test_sudo_sessions.t index e94b445..d7f0c61 100644 --- a/t/test_sudo_sessions.t +++ b/t/test_sudo_sessions.t @@ -32,7 +32,7 @@ $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("Bugzilla_password", $config->{admin_user_passwd}, "Enter admin password"); +$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"); @@ -60,7 +60,7 @@ $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("Bugzilla_password", $config->{admin_user_passwd}, "Enter admin password"); +$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"); @@ -72,10 +72,10 @@ ok($text =~ /The sudo session has been started/, "The sudo session has been star $sel->click_ok("link=Preferences"); $sel->wait_for_page_to_load_ok(WAIT_TIME); -$sel->title_is("User Preferences"); +$sel->title_is("General Preferences"); $sel->click_ok("link=Permissions"); $sel->wait_for_page_to_load_ok(WAIT_TIME); -$sel->title_is("User Preferences"); +$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"); @@ -89,13 +89,19 @@ $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"); +$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&Bugzilla_login=$config->{admin_user_login}&Bugzilla_password=$config->{admin_user_passwd}&target_login=$config->{admin_user_login}", undef, "Impersonate a user directly by providing all required data"); -$sel->title_is("Untrusted Authentication Request"); +$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. @@ -104,7 +110,7 @@ $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("Bugzilla_password", $config->{admin_user_passwd}, "Enter admin password"); +$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"); @@ -116,17 +122,24 @@ ok($error_msg =~ /^The user $config->{admin_user_login} may not be impersonated $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("Invalid Username Or Password"); +$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("Bugzilla_password", $config->{admin_user_passwd}, "Enter admin password"); +$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"); diff --git a/t/test_target_milestones.t b/t/test_target_milestones.t index bad55be..2533ad7 100644 --- a/t/test_target_milestones.t +++ b/t/test_target_milestones.t @@ -74,7 +74,7 @@ $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("link=Forget Search 'selenium_m0'"); +$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")); diff --git a/t/test_time_summary.t b/t/test_time_summary.t index f8ddad4..63cf5fa 100644 --- a/t/test_time_summary.t +++ b/t/test_time_summary.t @@ -34,7 +34,7 @@ $sel->is_text_present_ok("Additional hours worked: 2.6"); $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 to view/, "No data displayed"); +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. diff --git a/t/test_user_groups.t b/t/test_user_groups.t index cffd0f0..4b45b2d 100644 --- a/t/test_user_groups.t +++ b/t/test_user_groups.t @@ -68,7 +68,7 @@ $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 following group: Master'); +$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); @@ -84,7 +84,7 @@ $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 following group: Slave'); +$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); @@ -102,7 +102,7 @@ $sel->title_is('Edit user reg-user '); $sel->click_ok('link=find other users'); $sel->wait_for_page_to_load_ok(WAIT_TIME); $sel->title_is('Search users'); -$sel->is_checked_ok('enabled_only'); +$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'); @@ -117,7 +117,7 @@ $sel->title_is('Search users'); $sel->check_ok('grouprestrict'); $sel->select_ok('groupid', 'label=Master'); $sel->select_ok('matchtype', 'value=substr'); -$sel->uncheck_ok('enabled_only'); +$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'); @@ -130,7 +130,7 @@ $sel->title_is('Search users'); $sel->check_ok('grouprestrict'); $sel->select_ok('groupid', 'label=Slave'); $sel->select_ok('matchtype', 'value=substr'); -$sel->uncheck_ok('enabled_only'); +$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'); @@ -160,7 +160,7 @@ $sel->title_is('Search users'); $sel->check_ok('grouprestrict'); $sel->select_ok('groupid', 'label=Master'); $sel->select_ok('matchtype', 'value=substr'); -$sel->uncheck_ok('enabled_only'); +$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'); @@ -173,7 +173,7 @@ $sel->title_is('Search users'); $sel->check_ok('grouprestrict'); $sel->select_ok('groupid', 'label=Slave'); $sel->select_ok('matchtype', 'value=substr'); -$sel->uncheck_ok('enabled_only'); +$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'); @@ -195,7 +195,7 @@ sub cleanup_users { $sel->title_is("Search users"); $sel->type_ok('matchstr', '(master|slave|reg)@selenium.bugzilla.org'); $sel->select_ok('matchtype', 'value=regexp'); - $sel->uncheck_ok('enabled_only'); + $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"); @@ -229,7 +229,7 @@ sub cleanup_groups { $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"); + $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"); diff --git a/t/test_user_matching.t b/t/test_user_matching.t index 8140b02..3dd377c 100644 --- a/t/test_user_matching.t +++ b/t/test_user_matching.t @@ -33,7 +33,7 @@ $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/^Bug $bug1_id/); +$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. @@ -54,7 +54,7 @@ $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/^Bug $bug1_id/); +$sel->title_like(qr/^$bug1_id/); $sel->click_ok("cc_edit_area_showhide"); # This will return more than one account. @@ -82,7 +82,7 @@ $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/^Bug $bug1_id/); +$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 @@ -132,7 +132,7 @@ $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/^Bug $bug1_id/); +$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: @@ -145,7 +145,7 @@ $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/^Bug $bug1_id/); +$sel->title_like(qr/^$bug1_id/); $sel->click_ok("cc_edit_area_showhide"); # We can always see ourselves. diff --git a/t/test_user_preferences.t b/t/test_user_preferences.t index 1e41bb0..fe8deb6 100644 --- a/t/test_user_preferences.t +++ b/t/test_user_preferences.t @@ -31,14 +31,14 @@ $sel->title_is("Default Preferences"); $sel->click_ok("link=Preferences"); $sel->wait_for_page_to_load(WAIT_TIME); -$sel->title_is("User Preferences"); +$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("User Preferences"); +$sel->title_is("General Preferences"); # File a bug in the 'TestProduct' product. The form fields must follow user prefs. @@ -53,7 +53,7 @@ $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("editme_action"); +$sel->click_ok("summary_edit_action"); $sel->value_is("short_desc", $bug_summary); $sel->value_is("addselfcc", "off"); @@ -94,10 +94,10 @@ $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/^Bug $bug1_id /); +$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("editme_action"); +$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."); @@ -106,7 +106,7 @@ $sel->is_text_present_ok("The next bug I should see is this one."); $sel->click_ok("link=sel-tmp"); $sel->wait_for_page_to_load(WAIT_TIME); $sel->title_is("Bug List: sel-tmp"); -$sel->click_ok("link=Forget Search '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"); @@ -139,14 +139,14 @@ logout($sel); log_in($sel, $config, 'unprivileged'); $sel->click_ok("link=Preferences"); $sel->wait_for_page_to_load(WAIT_TIME); -$sel->title_is("User Preferences"); +$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("User Preferences"); +$sel->title_is("General Preferences"); # Create a new search named 'my_list'. @@ -174,7 +174,7 @@ $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/^Bug $bug1_id /); +$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); @@ -183,9 +183,9 @@ ok(!$sel->is_text_present("I should see the next bug"), "The updated bug is no l # 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=bug $bug1_id"); +$sel->click_ok("link=$bug1_id"); $sel->wait_for_page_to_load(WAIT_TIME); -$sel->title_like(qr/^Bug $bug1_id /); +$sel->title_like(qr/^$bug1_id /); $sel->is_text_present("1 user including you"); # Delete the saved search and log out. @@ -193,7 +193,7 @@ $sel->is_text_present("1 user including you"); $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=Forget Search '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"); diff --git a/t/test_user_privs.t b/t/test_user_privs.t index 1074694..7eae005 100644 --- a/t/test_user_privs.t +++ b/t/test_user_privs.t @@ -34,12 +34,12 @@ ok($text =~ /You need to log in before you can comment on or make changes to thi $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->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/^Bug $bug1_id/, "Display bug $bug1_id"); +$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. diff --git a/t/test_votes.t b/t/test_votes.t index 2912df7..35b8fb9 100644 --- a/t/test_votes.t +++ b/t/test_votes.t @@ -26,20 +26,12 @@ $sel->type_ok("description", "A great new product"); $sel->type_ok("votesperuser", 10); $sel->type_ok("maxvotesperbug", 5); $sel->type_ok("votestoconfirm", 3); -$sel->click_ok('//input[@type="submit" and @value="Add"]'); -$sel->wait_for_page_to_load_ok(WAIT_TIME); -$sel->title_is("Product Created"); -$sel->click_ok("link=add at least one component"); -$sel->wait_for_page_to_load_ok(WAIT_TIME); -$sel->title_is("Add component to the Eureka product"); $sel->type_ok("component", "Pegasus"); -$sel->type_ok("description", "A constellation in the north hemisphere."); +$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("create"); +$sel->click_ok('add-product'); $sel->wait_for_page_to_load_ok(WAIT_TIME); -$sel->title_is("Component Created"); -my $text = trim($sel->get_text("message")); -ok($text =~ qr/The component Pegasus has been created/, "Component 'Pegasus' created"); +$sel->title_is("Product Created"); # Create a new bug with the CONFIRMED status. @@ -117,7 +109,7 @@ $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"); -$text = trim($sel->get_text("error_msg")); +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"); @@ -170,7 +162,7 @@ $sel->is_text_present_ok("removed votes for bug $bug2_id from " . $config->{admi $sel->click_ok("link=$bug2_id"); $sel->wait_for_page_to_load_ok(WAIT_TIME); -$sel->title_like(qr/Bug $bug2_id /); +$sel->title_like(qr/$bug2_id /); $text = trim($sel->get_text("votes_container")); ok($text =~ /4 votes/, "4 votes remaining"); @@ -190,7 +182,7 @@ $sel->is_text_present_ok("removed votes for bug"); $sel->click_ok("link=$bug3_id"); $sel->wait_for_page_to_load_ok(WAIT_TIME); -$sel->title_like(qr/Bug $bug3_id /); +$sel->title_like(qr/$bug3_id /); $text = trim($sel->get_text("votes_container")); ok($text =~ /2 votes/, "2 votes remaining"); diff --git a/t/webservice_bug_add_attachment.t b/t/webservice_bug_add_attachment.t index 61cb4f9..c36ec77 100644 --- a/t/webservice_bug_add_attachment.t +++ b/t/webservice_bug_add_attachment.t @@ -34,7 +34,7 @@ sub attach { } my ($public_bug, $private_bug) = - $xmlrpc->bz_create_test_bugs($config, 'private'); + $xmlrpc->bz_create_test_bugs('private'); my $public_id = $public_bug->{id}; my $private_id = $private_bug->{id}; diff --git a/t/webservice_bug_attachments.t b/t/webservice_bug_attachments.t index aad188b..4db90c6 100644 --- a/t/webservice_bug_attachments.t +++ b/t/webservice_bug_attachments.t @@ -6,7 +6,7 @@ use QA::Tests qw(STANDARD_BUG_TESTS PRIVATE_BUG_USER); use Data::Dumper; use List::Util qw(first); use MIME::Base64; -use Test::More tests => 337; +use Test::More tests => 313; my ($config, @clients) = get_rpc_clients(); ################ @@ -17,6 +17,7 @@ our %attachments; sub post_bug_success { my ($call, $t) = @_; + my $bugs = $call->result->{bugs}; is(scalar keys %$bugs, 1, "Got exactly one bug") or diag(Dumper($call->result)); @@ -26,14 +27,13 @@ sub post_bug_success { foreach my $alias (qw(public_bug private_bug)) { foreach my $is_private (0, 1) { my $find_desc = "${alias}_${is_private}"; - my $attachment = first { $_->{description} eq $find_desc } + my $attachment = first { $_->{summary} eq $find_desc } reverse @$bug_attachments; if ($attachment) { $attachments{$find_desc} = $attachment->{id}; } } } - } foreach my $rpc (@clients) { @@ -130,10 +130,8 @@ sub post_success { "content_type is correct"); cmp_ok($attachment->{file_name}, '=~', qr/^\w+\.pl$/, "filename is in the expected format"); - is($attachment->{$_}, $config->{QA_Selenium_TEST_user_login}, - "$_ is the correct user") foreach qw(attacher creator); - is($attachment->{summary}, $attachment->{description}, - "summary and description have the same values"); + is($attachment->{creator}, $config->{QA_Selenium_TEST_user_login}, + "creator is the correct user"); my $data = $attachment->{data}; $data = decode_base64($data) if $rpc->isa('QA::RPC::JSONRPC'); is($data, $content, 'data is correct'); diff --git a/t/webservice_bug_comments.t b/t/webservice_bug_comments.t index e7701c5..6a93bdb 100644 --- a/t/webservice_bug_comments.t +++ b/t/webservice_bug_comments.t @@ -8,7 +8,7 @@ use lib qw(lib); use DateTime; use QA::Util; use QA::Tests qw(STANDARD_BUG_TESTS PRIVATE_BUG_USER); -use Test::More tests => 358; +use Test::More tests => 331; my ($config, @clients) = get_rpc_clients(); # These gets populated when we call Bug.add_comment. @@ -34,12 +34,10 @@ sub test_comments { my %reverse_map = reverse %comments; my $expected_text = $reverse_map{$expected_id}; is($comment->{text}, $expected_text, "comment has the correct text"); - + my $priv_login = $rpc->bz_config->{PRIVATE_BUG_USER . '_user_login'}; - is($comment->{author}, $priv_login, "comment author is correct"); is($comment->{creator}, $priv_login, "comment creator is correct"); - my $creation_day; if ($rpc->isa('QA::RPC::XMLRPC')) { $creation_day = $creation_time->ymd(''); @@ -51,7 +49,7 @@ sub test_comments { "comment time has the right format"); } else { - foreach my $field (qw(id text author creator time)) { + foreach my $field (qw(id text creator time)) { ok(defined $comment->{$field}, "$field is defined"); } } diff --git a/t/webservice_bug_create.t b/t/webservice_bug_create.t index 657024d..6cf8d6c 100644 --- a/t/webservice_bug_create.t +++ b/t/webservice_bug_create.t @@ -122,7 +122,7 @@ my $fields = { }, alias => { long => { - faultstring => 'Bug aliases cannot be longer than 20 characters', + faultstring => 'Bug aliases cannot be longer than 40 characters', value => 'MyyyyyyyyyyyyyyyyyyBugggggggggggggggggggggg' }, existing => { @@ -135,7 +135,7 @@ my $fields = { }, commma_or_space_separated => { faultstring => 'contains one or more commas or spaces', - value => 'Bug 12345' + value => ['Bug 12345'] }, }, diff --git a/t/webservice_bug_get.t b/t/webservice_bug_get.t index d219af7..cf6125a 100644 --- a/t/webservice_bug_get.t +++ b/t/webservice_bug_get.t @@ -9,7 +9,7 @@ use Data::Dumper; use DateTime; use QA::Util; use QA::Tests qw(bug_tests PRIVATE_BUG_USER); -use Test::More tests => 1012; +use Test::More tests => 988; my ($config, @clients) = get_rpc_clients(); my $xmlrpc = $clients[0]; @@ -89,10 +89,8 @@ sub post_success { my $bug = $call->result->{bugs}->[0]; if ($t->{user} && $t->{user} eq 'admin') { - ok(exists $bug->{estimated_time} && exists $bug->{remaining_time} - && exists $bug->{deadline}, + ok(exists $bug->{estimated_time} && exists $bug->{remaining_time}, 'Admin correctly gets time-tracking fields'); - is($bug->{deadline}, '2038-01-01', 'deadline is correct'); cmp_ok($bug->{estimated_time}, '==', '10.0', 'estimated_time is correct'); @@ -100,8 +98,7 @@ sub post_success { 'remaining_time is correct'); } else { - ok(!exists $bug->{estimated_time} && !exists $bug->{remaining_time} - && !exists $bug->{deadline}, + ok(!exists $bug->{estimated_time} && !exists $bug->{remaining_time}, 'Time-tracking fields are not returned to non-privileged users'); } diff --git a/t/webservice_bug_legal_values.t b/t/webservice_bug_legal_values.t index 9149599..43a23fb 100644 --- a/t/webservice_bug_legal_values.t +++ b/t/webservice_bug_legal_values.t @@ -73,7 +73,7 @@ my @extra_tests = ( test => "Passing product_id without 'field' throws an error", }, { args => { field => INVALID_FIELD_NAME }, - error => "Can't use " . INVALID_FIELD_NAME . " as a field name", + error => "Can't use \"" . INVALID_FIELD_NAME . "\" as a field name", test => 'Invalid field name' }, ); diff --git a/t/webservice_bug_search.t b/t/webservice_bug_search.t index ffd771b..ba81dde 100644 --- a/t/webservice_bug_search.t +++ b/t/webservice_bug_search.t @@ -10,11 +10,33 @@ use QA::Tests qw(PRIVATE_BUG_USER); use DateTime; use List::MoreUtils qw(uniq); use Test::More; +use Data::Dumper; my ($config, @clients) = get_rpc_clients(); -plan tests => $config->{test_extensions} ? 515 : 506; +plan tests => $config->{test_extensions} ? 531 : 522; my ($public_bug, $private_bug) = $clients[0]->bz_create_test_bugs('private'); + +# Add aliases to both bugs +$public_bug->{alias} = random_string(40); +$private_bug->{alias} = random_string(40); +my $alias_tests = [ + { user => 'editbugs', + args => { ids => [ $public_bug->{id} ], alias => $public_bug->{alias} }, + test => 'Add alias to public bug' }, + { user => PRIVATE_BUG_USER, + args => { ids => [ $private_bug->{id} ], + cc => { add => [ $config->{'editbugs_user_login'} ] } }, + test => 'Add editusers to cc of private bug' }, + { user => 'editbugs', + args => { ids => [ $private_bug->{id} ], alias => $private_bug->{alias} }, + test => 'Add alias to private bug' }, + { user => PRIVATE_BUG_USER, + args => { ids => [ $private_bug->{id} ], + cc => { remove => [ $config->{'editbugs_user_login'} ] } }, + test => 'Remove editusers from cc of private bug' }, +]; +$clients[0]->bz_run_tests(tests => $alias_tests, method => 'Bug.update'); my @tests; foreach my $field (keys %$public_bug) { @@ -27,7 +49,6 @@ foreach my $field (keys %$public_bug) { push(@tests, $test); } - push(@tests, ( { args => { offset => 1 }, test => "Offset without limit fails", @@ -137,6 +158,7 @@ push(@tests, sub post_success { my ($call, $t) = @_; my $bugs = $call->result->{bugs}; + my $expected_count = $t->{bugs}; $expected_count = 1 if !defined $expected_count; if ($expected_count) { diff --git a/t/webservice_bug_update.t b/t/webservice_bug_update.t index 193cdbe..1bb4d86 100644 --- a/t/webservice_bug_update.t +++ b/t/webservice_bug_update.t @@ -5,7 +5,7 @@ use Data::Dumper; use QA::Util; use QA::Tests qw(PRIVATE_BUG_USER STANDARD_BUG_TESTS); use Storable qw(dclone); -use Test::More tests => 957; +use Test::More tests => 937; use constant NONEXISTANT_BUG => 12_000_000; @@ -23,7 +23,20 @@ sub get_tests { my ($public_bug, $second_bug) = $rpc->bz_create_test_bugs(); my ($public_id, $second_id) = ($public_bug->{id}, $second_bug->{id}); - + + # Add aliases to both bugs + $public_bug->{alias} = random_string(40); + $second_bug->{alias} = random_string(40); + my $alias_tests = [ + { user => 'editbugs', + args => { ids => [ $public_id ], alias => $public_bug->{alias} }, + test => 'Add alias to public bug' }, + { user => 'editbugs', + args => { ids => [ $second_id ], alias => $second_bug->{alias} }, + test => 'Add alias to second bug' }, + ]; + $rpc->bz_run_tests(tests => $alias_tests, method => 'Bug.update'); + my $comment_call = $rpc->bz_call_success( 'Bug.comments', { ids => [$public_id, $second_id] }); $public_bug->{comment} = @@ -308,7 +321,7 @@ sub invalid_values { my %values = ( alias => [ - { value => random_string(21), + { value => random_string(41), error => 'aliases cannot be longer than', test => 'alias cannot be too long' }, { value => $second_bug->{alias}, @@ -317,12 +330,6 @@ sub invalid_values { { value => 123456, error => 'at least one letter', test => 'numeric alias fails' }, - { value => random_string(6) . ' ' . random_string(6), - error => 'contains one or more commas or spaces', - test => 'alias with space fails' }, - { value => random_string(6) . ',' . random_string(6), - error => 'contains one or more commas or spaces', - test => 'alias with comma fails' }, { value => random_string(20), ids => [$public_id, $second_id], error => 'aliases when modifying multiple', test => 'setting alias on multiple bugs fails' }, @@ -394,11 +401,6 @@ sub invalid_values { { value => '2037', error => 'is not a legal date', test => 'year alone fails in deadline' }, - # We use PRIVATE_BUG_USER because he can modify the bug, but - # can't change time-tracking fields. - { value => '2037-01-02', user => PRIVATE_BUG_USER, - error => 'only a user with the required permissions', - test => 'non-timetracker can not set deadline' }, ], dupe_of => [ @@ -447,13 +449,13 @@ sub invalid_values { keywords => [ { value => { add => [random_string(20)] }, - error => 'legal keyword names are listed', + error => 'See the list of available keywords', test => 'adding invalid keyword fails' }, { value => { remove => [random_string(20)] }, - error => 'legal keyword names are listed', + error => 'See the list of available keywords', test => 'removing invalid keyword fails' }, { value => { set => [random_string(20)] }, - error => 'legal keyword names are listed', + error => 'See the list of available keywords', test => 'setting invalid keyword fails' }, ], @@ -642,7 +644,7 @@ sub post_success { sub _check_changes { my ($bug, $field, $t) = @_; - + my $changes = $bug->{changes}->{$field}; ok(defined $changes, "$field was changed") or diag Dumper($bug, $t); diff --git a/t/webservice_bugzilla.t b/t/webservice_bugzilla.t index a0575bd..80035db 100644 --- a/t/webservice_bugzilla.t +++ b/t/webservice_bugzilla.t @@ -5,7 +5,7 @@ use strict; use warnings; use lib qw(lib); -use Test::More tests => 15 * 3; +use Test::More tests => 11 * 3; use QA::Util; my ($config, @clients) = get_rpc_clients(); @@ -31,14 +31,8 @@ foreach my $rpc (@clients) { my $time_call = $rpc->bz_call_success('Bugzilla.time'); my $time_result = $time_call->result; - foreach my $type (qw(db_time web_time web_time_utc)) { + foreach my $type (qw(db_time web_time)) { cmp_ok($time_result->{$type}, '=~', $rpc->DATETIME_REGEX, "Bugzilla.time returns a datetime for $type"); } - cmp_ok($time_result->{tz_offset}, '=~', qr/^(?:\+|-)\d{4}$/, - "Bugzilla.time's tz_offset is in the right format"); - cmp_ok($time_result->{tz_short_name}, '=~', qr/^[A-Z]{3,4}/, - "Bugzilla.time's tz_short_name is in the right format"); - cmp_ok($time_result->{tz_name}, '=~', qr{^(?:(?:\w+/\w+)|(?:UTC))$}, - "Bugzilla.time's tz_name is in the right format"); } diff --git a/t/webservice_user_create.t b/t/webservice_user_create.t index 2774e72..b6216ca 100644 --- a/t/webservice_user_create.t +++ b/t/webservice_user_create.t @@ -6,7 +6,7 @@ use strict; use warnings; use lib qw(lib); use QA::Util; -use Test::More tests => 69; +use Test::More tests => 75; my ($config, $xmlrpc, $jsonrpc, $jsonrpc_get) = get_rpc_clients(); use constant NEW_PASSWORD => 'password'; @@ -18,7 +18,7 @@ use constant PASSWORD_TOO_SHORT => 'a'; use constant INVALID_EMAIL => '()[]\;:,<>@webservice.test'; sub new_login { - return 'created_' . random_string() . '@webservice.test'; + return 'created_' . random_string(@_) . '@webservice.test'; } sub post_success { @@ -68,6 +68,12 @@ foreach my $rpc ($jsonrpc, $xmlrpc) { error => "didn't pass our syntax checking", test => 'Invalid email address fails', }, + { user => 'admin', + args => { email => new_login(128), full_name => NEW_FULLNAME, + password => NEW_PASSWORD }, + error => "didn't pass our syntax checking", + test => 'Too long (> 127 chars) email address fails', + }, { user => 'admin', args => { email => $config->{unprivileged_user_login}, full_name => NEW_FULLNAME, password => NEW_PASSWORD }, diff --git a/t/webservice_user_login_logout.t b/t/webservice_user_login_logout.t index fbbe02e..81ce465 100644 --- a/t/webservice_user_login_logout.t +++ b/t/webservice_user_login_logout.t @@ -14,7 +14,7 @@ use constant INVALID_EMAIL => '@invalid_user@'; my $user = $config->{unprivileged_user_login}; my $pass = $config->{unprivileged_user_passwd}; -my $error = "The username or password you entered is not valid"; +my $error = "The login or password you entered is not valid"; my @tests = ( { user => 'unprivileged', @@ -51,7 +51,6 @@ my @tests = ( password => $config->{disabled_user_passwd} }, error => "!!This is the text!!", test => "Can't log in with a disabled account", - clears_cookies => 1, }, { args => { login => $config->{disabled_user_login}, password => '*' }, error => $error, diff --git a/travis.sh b/travis.sh deleted file mode 100755 index dc238b9..0000000 --- a/travis.sh +++ /dev/null @@ -1,158 +0,0 @@ -#!/bin/bash -# 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. - -# Setup starts here -cd $TRAVIS_BUILD_DIR - -# Allow alias expansion inside shell scripts -shopt -s expand_aliases - -# Package installation section -echo -en 'travis_fold:start:packages\r' -echo "== Installing OS packages" -sudo apt-get install -qq -y \ - perlmagick libssl-dev g++ libgd2-xpm-dev libmysqlclient-dev libpq5 \ - postgresql-server-dev-9.1 python-sphinx xmlto lynx texlive-lang-cyrillic \ - ldp-docbook-dsssl jade jadetex lynx apache2 xvfb -echo -en 'travis_fold:end:packages\r' - -# Environment need for docs building -export JADE_PUB=/usr/share/sgml/declaration -export LDP_HOME=/usr/share/sgml/docbook/stylesheet/dsssl/ldp - -# Install dependencies from Build.PL -echo -en 'travis_fold:start:perl_dependencies\r' -echo "== Installing Perl dependencies" -alias cpanm='cpanm --quiet --notest --reinstall' -cpanm DateTime -cpanm Module::Build # Need latest build -cpanm Software::License # Needed by Module::Build to find proper Mozilla license -cpanm Pod::Coverage -cpanm DBD::mysql -cpanm DBD::Pg -cpanm Cache::Memcached::GetParserXS # FIXME test-checksetup.pl fails without this -cpanm XMLRPC::Lite # Due to the SOAP::Lite split -cpanm Test::WWW::Selenium # For webservice and selenium tests -cpanm --installdeps --with-recommends . # Install dependencies reported by Build.PL -echo -en 'travis_fold:end:perl_dependencies\r' - -# Link /usr/bin/perl to the current perlbrew perl so that the Bugzilla cgi scripts will work properly -# PERLBREW_ROOT and PERLBREW_PERL are set by the perlbrew binary when switch perl versions -echo "== Fixing Perl" -sudo mv /usr/bin/perl /usr/bin/perl.bak -sudo ln -s $PERLBREW_ROOT/perls/$PERLBREW_PERL/bin/perl /usr/bin/perl - -# Basic sanity tests -if [ "$TEST_SUITE" = "sanity" ]; then - echo "== Running sanity tests" - perl Build.PL - perl Build - perl Build test - exit $? -fi - -# Documentation build testing -if [ "$TEST_SUITE" = "docs" ]; then - echo "== Running documentation build" - cd docs - perl makedocs.pl --with-pdf - exit $? -fi - -# We need to replace some variables in the config files from the Travis CI environment -echo "== Updating config files" -sed -e "s?%TRAVIS_BUILD_DIR%?$(pwd)?g" --in-place qa/config/selenium_test.conf -sed -e "s?%USER%?$USER?g" --in-place qa/config/checksetup_answers.txt -if [ "$DB" = "" ]; then - DB=mysql -fi -sed -e "s?%DB%?$DB?g" --in-place qa/config/checksetup_answers.txt -sed -e "s?%TRAVIS_BUILD_DIR%?$(pwd)?g" --in-place qa/config/config-checksetup-mysql -sed -e "s?%TRAVIS_BUILD_DIR%?$(pwd)?g" --in-place qa/config/config-checksetup-pg -if [ "$TEST_SUITE" == "checksetup" ]; then - sed -e "s?%DB_NAME%?bugs_checksetup?g" --in-place qa/config/checksetup_answers.txt -else - sed -e "s?%DB_NAME%?bugs?g" --in-place qa/config/checksetup_answers.txt -fi - -# MySQL related setup -if [ "$DB" = "mysql" ]; then - echo "== Setting up MySQL" - mysql -u root mysql -e "GRANT ALL PRIVILEGES ON *.* TO bugs@localhost IDENTIFIED BY 'bugs'; FLUSH PRIVILEGES;" -fi - -# PostgreSQL related setup -if [ "$DB" = "pg" ]; then - echo "== Setting up PostgreSQL" - sudo -u postgres createuser --superuser bugs - sudo -u postgres psql -U postgres -d postgres -c "alter user bugs with password 'bugs';" -fi - -# Checksetup test which tests schema changes from older versions to the current -if [ "$TEST_SUITE" = "checksetup" ] && [ "$DB" = "mysql" ]; then - echo "== Running checksetup upgrade tests for MySQL" - perl qa/test-checksetup.pl --full --config config/config-checksetup-mysql - exit $? -fi - -if [ "$TEST_SUITE" = "checksetup" ] && [ "$DB" = "pg" ]; then - echo "== Running checksetup upgrade tests for PostgreSQL" - perl qa/test-checksetup.pl --full --config config/config-checksetup-pg - exit $? -fi - -# Configure Apache to serve from our build directory and restart -echo "== Setting up Apache" -sed -e "s?%TRAVIS_BUILD_DIR%?$(pwd)?g" --in-place qa/config/bugzilla.conf -sudo cp qa/config/bugzilla.conf /etc/apache2/sites-available/default -sudo sed -e "s?APACHE_RUN_USER=www-data?APACHE_RUN_USER=$USER?g" --in-place /etc/apache2/envvars -sudo sed -e "s?APACHE_RUN_GROUP=www-data?APACHE_RUN_GROUP=$USER?g" --in-place /etc/apache2/envvars -sudo service apache2 stop; sudo rm -rf /var/lock/apache2; sudo service apache2 start - -# We have to run checksetup.pl twice as the first run creates localconfig -echo "== Running checksetup" -perl checksetup.pl qa/config/checksetup_answers.txt -perl checksetup.pl qa/config/checksetup_answers.txt - -# Add patch file used by tests. FIXME: make this a config option -sudo mkdir -p /var/www/html/selenium/bugzilla -sudo cp qa/config/patch.diff /var/www/html/selenium/bugzilla - -# Create test data in the SQLite database for use by the extended test suite -echo "== Generating test data" -cd $TRAVIS_BUILD_DIR/qa/config -perl -Mlib=$TRAVIS_BUILD_DIR/lib generate_test_data.pl -cd $TRAVIS_BUILD_DIR/qa/t - -# Selenium UI Tests -if [ "$TEST_SUITE" = "selenium" ]; then - # Start the virtual frame buffer - echo "== Starting virtual frame buffer" - export DISPLAY=:99.0 - sudo sh -e /etc/init.d/xvfb start - sleep 5 - - # Download and start the selenium server - echo "== Downloading and starting Selenium server" - wget http://selenium-release.storage.googleapis.com/2.41/selenium-server-standalone-2.41.0.jar - java -jar selenium-server-standalone-2.41.0.jar -DfirefoxDefaultPath=/usr/lib64/firefox/firefox -log ~/sel-`date +%Y%m%d-%H%M%S`.log & - sleep 15 - - echo "== Running Selenium UI tests" - perl -Mlib=$TRAVIS_BUILD_DIR/lib /usr/bin/prove -v -f -I$TRAVIS_BUILD_DIR/lib test_*.t - exit $? -fi - -# WebService Tests -if [ "$TEST_SUITE" = "webservices" ]; then - echo "== Running WebService tests" - perl -Mlib=$TRAVIS_BUILD_DIR/lib /usr/bin/prove -v -f -I$TRAVIS_BUILD_DIR/lib webservice_*.t - exit $? -fi - -exit 0