diff --git a/config/generate_test_data.pl b/config/generate_test_data.pl index 1ad45c8..515e5bf 100644 --- a/config/generate_test_data.pl +++ b/config/generate_test_data.pl @@ -40,15 +40,24 @@ BEGIN # Set Parameters ########################################################################## -my $params_modified; -# 'usebugaliases' must be turned on to create bugs with an alias. -# It's also expected to be turned on by some webservice_*.t scripts. +my $params_modified = 0; +# Some parameters must be turned on to create bugs requiring them. +# They are also expected to be turned on by some webservice_*.t scripts. if (!Bugzilla->params->{usebugaliases}) { SetParam('usebugaliases', 1); - write_params(); + $params_modified = 1; +} +if (!Bugzilla->params->{useqacontact}) { + SetParam('useqacontact', 1); + $params_modified = 1; +} +# Do not try to send emails for real! +if (Bugzilla->params->{mail_delivery_method} ne 'Test') { + SetParam('mail_delivery_method', 'Test'); $params_modified = 1; } +write_params() if $params_modified; ########################################################################## # Create Users ########################################################################## @@ -392,7 +401,7 @@ BEGIN 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', inclusions => ['Another Product:c1']}, + target_type => 'b', cc_list => '', inclusions => ['Another Product:c1']}, ); print "creating flag types...\n"; @@ -484,11 +493,11 @@ BEGIN if (Bugzilla->params->{insidergroup} ne 'QA-Selenium-TEST') { SetParam('insidergroup', 'QA-Selenium-TEST'); - write_params(); $params_modified = 1; } if ($params_modified) { + write_params(); print <{bz_config} ||= QA::Util::get_config(); + return $self->{bz_config}; +} + +################################ +# Helpers for RPC test scripts # +################################ + +sub bz_log_in { + my ($self, $user) = @_; + my $username = $self->bz_config->{"${user}_user_login"}; + my $password = $self->bz_config->{"${user}_user_passwd"}; + + my $call = $self->bz_call_success( + 'User.login', { login => $username, password => $password }); + cmp_ok($call->result->{id}, 'gt', 0, "Logged in as $user"); + + # 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 { + my ($self, $method, $args, $test_name) = @_; + my $call = $self->call($method, $args); + $test_name ||= "$method returned successfully"; + ok(!defined $call->fault, $test_name) or diag($call->faultstring); + return $call; +} + +sub bz_call_fail { + my ($self, $method, $args, $faultstring, $test_name) = @_; + my $call = $self->call($method, $args); + $test_name ||= "$method failed (as intended)"; + ok(defined $call->fault, $test_name) + or diag("Returned: " . Dumper($call->result)); + if (defined $faultstring) { + cmp_ok(trim($call->faultstring), '=~', $faultstring, + "Got correct fault for $method"); + } + return $call; +} + +sub bz_get_products { + my ($self) = @_; + $self->bz_log_in('QA_Selenium_TEST'); + + my $accessible = $self->bz_call_success('Product.get_accessible_products'); + my $prod_call = $self->bz_call_success('Product.get', $accessible->result); + my %products; + foreach my $prod (@{ $prod_call->result->{products} }) { + $products{$prod->{name}} = $prod->{id}; + } + + $self->bz_call_success('User.logout'); + return \%products; +} + +sub bz_run_tests { + my ($self, %params) = @_; + # Required params + my $config = $self->bz_config; + my $tests = $params{tests}; + my $method = $params{method}; + + # Optional params + my $post_success = $params{post_success}; + + my $former_user = ''; + foreach my $t (@$tests) { + # Only logout/login if the user has changed since the last test + # (this saves us LOTS of needless logins). + my $user = $t->{user} || ''; + if ($former_user ne $user) { + $self->bz_call_success('User.logout') if $former_user; + $self->bz_log_in($user) if $user; + $former_user = $user; + } + + if ($t->{error}) { + $self->bz_call_fail($method, $t->{args}, $t->{error}, $t->{test}); + } + else { + my $call = $self->bz_call_success($method, $t->{args}, $t->{test}); + if ($call->result && $post_success) { + $post_success->($call, $t, $self); + } + } + } + + $self->bz_call_success('User.logout') if $former_user; +} + +1; + +__END__ diff --git a/t/lib/QA/Tests.pm b/t/lib/QA/Tests.pm index 495647e..bff962b 100644 --- a/t/lib/QA/Tests.pm +++ b/t/lib/QA/Tests.pm @@ -6,12 +6,43 @@ use base qw(Exporter); our @EXPORT_OK = qw( PRIVATE_BUG_USER STANDARD_BUG_TESTS + create_bug_fields ); use constant INVALID_BUG_ID => -1; use constant INVALID_BUG_ALIAS => 'aaaaaaa12345'; use constant PRIVATE_BUG_USER => 'QA_Selenium_TEST'; +use constant CREATE_BUG => { + 'priority' => 'P1', + 'status' => 'NEW', + 'version' => 'unspecified', + 'reporter' => 'editbugs', + 'bug_file_loc' => '', + 'description' => '-- Comment Created By Bugzilla XML-RPC Tests --', + 'cc' => ['unprivileged'], + 'component' => 'TestComponent', + 'platform' => 'All', + 'assigned_to' => 'editbugs', + 'summary' => 'XML-RPC Test Bug', + 'product' => 'TestProduct', + 'op_sys' => 'Linux', + 'severity' => 'normal', + 'qa_contact' => 'canconfirm', + url => 'http://www.bugzilla.org/', +}; + +sub create_bug_fields { + my ($config) = @_; + my %bug = %{ CREATE_BUG() }; + foreach my $field (qw(reporter assigned_to qa_contact)) { + my $value = $bug{$field}; + $bug{$field} = $config->{"${value}_user_login"}; + } + $bug{cc} = [map { $config->{$_ . "_user_login"} } @{ $bug{cc} }]; + return \%bug; +} + use constant STANDARD_BUG_TESTS => [ { args => { ids => ['private_bug'] }, error => "You are not authorized to access", diff --git a/t/lib/QA/Util.pm b/t/lib/QA/Util.pm index 3141507..3e81338 100644 --- a/t/lib/QA/Util.pm +++ b/t/lib/QA/Util.pm @@ -8,7 +8,6 @@ use HTTP::Cookies; use Test::More; use Test::WWW::Selenium; use WWW::Selenium::Util qw(server_is_running); -use XMLRPC::Lite; use base qw(Exporter); @QA::Util::EXPORT = qw( @@ -28,12 +27,6 @@ use base qw(Exporter); get_selenium get_xmlrpc_client - xmlrpc_log_in - xmlrpc_call_success - xmlrpc_call_fail - xmlrpc_get_product_ids - xmlrpc_run_tests - WAIT_TIME CHROME_MODE ); @@ -104,110 +97,14 @@ sub get_xmlrpc_client { my $xmlrpc_url = $config->{browser_url} . "/" . $config->{bugzilla_installation} . "/xmlrpc.cgi"; - + require QA::RPC; # A temporary cookie jar that isn't saved after the script closes. my $cookie_jar = new HTTP::Cookies(); - my $rpc = new XMLRPC::Lite(proxy => $xmlrpc_url); + my $rpc = new QA::RPC(proxy => $xmlrpc_url); $rpc->transport->cookie_jar($cookie_jar); return ($rpc, $config); } -############################### -# Helpers for XML-RPC scripts # -############################### - -sub xmlrpc_log_in { - my ($rpc, $config, $user) = @_; - my $username = $config->{"${user}_user_login"}; - my $password = $config->{"${user}_user_passwd"}; - - my $call = xmlrpc_call_success($rpc, 'User.login', - { login => $username, password => $password }); - cmp_ok($call->result->{id}, 'gt', 0, "Logged in as $user"); - - # Save the cookies in the cookie file - $rpc->transport->cookie_jar->extract_cookies( - $rpc->transport->http_response); - $rpc->transport->cookie_jar->save; -} - -sub xmlrpc_call_success { - my ($rpc, $method, $args, $test_name) = @_; - my $call = $rpc->call($method, $args); - $test_name ||= "$method returned successfully"; - ok(!defined $call->fault, $test_name) or diag($call->faultstring); - return $call; -} - -sub xmlrpc_call_fail { - my ($rpc, $method, $args, $faultstring, $test_name) = @_; - my $call = $rpc->call($method, $args); - $test_name ||= "$method failed (as intended)"; - ok(defined $call->fault, $test_name) - or diag("Returned: " . Dumper($call->result)); - if (defined $faultstring) { - cmp_ok(trim($call->faultstring), '=~', $faultstring, - "Got correct fault for $method"); - } - return $call; -} - -sub xmlrpc_get_product_ids { - my ($rpc, $config) = @_; - xmlrpc_log_in($rpc, $config, 'QA_Selenium_TEST'); - - my $accessible = xmlrpc_call_success($rpc, - 'Product.get_accessible_products'); - my $prod_call = xmlrpc_call_success($rpc, 'Product.get', - $accessible->result); - my %products; - foreach my $prod (@{ $prod_call->result->{products} }) { - $products{$prod->{name}} = $prod->{id}; - } - - xmlrpc_call_success($rpc, 'User.logout'); - - return \%products; -} - -sub xmlrpc_run_tests { - my %params = @_; - # Required params - my $rpc = $params{rpc}; - my $config = $params{config}; - my $tests = $params{tests}; - my $method = $params{method}; - - # Optional params - my $post_success = $params{post_success}; - - my $former_user = ''; - foreach my $t (@$tests) { - # Only logout/login if the user has changed since the last test - # (this saves us LOTS of needless logins). - my $user = $t->{user} || ''; - if ($former_user ne $user) { - xmlrpc_call_success($rpc, 'User.logout') if $former_user; - xmlrpc_log_in($rpc, $config, $user) if $user; - $former_user = $user; - } - - if ($t->{error}) { - xmlrpc_call_fail($rpc, $method, $t->{args}, $t->{error}, - $t->{test}); - } - else { - my $call = xmlrpc_call_success($rpc, $method, $t->{args}, - $t->{test}); - if ($call->result && $post_success) { - $post_success->($call, $t); - } - } - } - - xmlrpc_call_success($rpc, 'User.logout') if $former_user; -} - ################################ # Helpers for Selenium Scripts # ################################ diff --git a/t/test_custom_fields.t b/t/test_custom_fields.t index c0bc424..19c2ad6 100644 --- a/t/test_custom_fields.t +++ b/t/test_custom_fields.t @@ -38,7 +38,8 @@ $sel->value_is("obsolete", "off"); $sel->click_ok("create"); $sel->wait_for_page_to_load_ok(WAIT_TIME); $sel->title_is("Custom Field Created"); -$sel->is_text_present_ok("The new custom field \'cf_qa_freetext_$bug1_id\' has been successfully created."); +$sel->is_text_present_ok("The new custom field 'cf_qa_freetext_$bug1_id' has been successfully created."); + $sel->click_ok("link=Add a new custom field"); $sel->wait_for_page_to_load_ok(WAIT_TIME); $sel->title_is("Add a new Custom Field"); @@ -54,28 +55,30 @@ $sel->value_is("obsolete", "off"); $sel->click_ok("create"); $sel->wait_for_page_to_load_ok(WAIT_TIME); $sel->title_is("Custom Field Created"); -$sel->is_text_present_ok("The new custom field \'cf_qa_list_$bug1_id\' has been successfully created."); +$sel->is_text_present_ok("The new custom field 'cf_qa_list_$bug1_id' has been successfully created."); # Add values to the custom fields. $sel->click_ok("link=cf_qa_list_$bug1_id"); $sel->wait_for_page_to_load_ok(WAIT_TIME); -$sel->title_is("Edit the Custom Field \'cf_qa_list_$bug1_id\' (List$bug1_id)"); +$sel->title_is("Edit the Custom Field 'cf_qa_list_$bug1_id' (List$bug1_id)"); $sel->click_ok("link=Edit legal values for this field"); $sel->wait_for_page_to_load_ok(WAIT_TIME); -$sel->title_is("Select value for the \'List$bug1_id\' (cf_qa_list_$bug1_id) field"); +$sel->title_is("Select value for the 'List$bug1_id' (cf_qa_list_$bug1_id) field"); + $sel->click_ok("link=Add"); $sel->wait_for_page_to_load_ok(WAIT_TIME); -$sel->title_is("Add Value for the \'List$bug1_id\' (cf_qa_list_$bug1_id) field"); +$sel->title_is("Add Value for the 'List$bug1_id' (cf_qa_list_$bug1_id) field"); $sel->type_ok("value", "have fun?"); $sel->type_ok("sortkey", "805"); $sel->click_ok("create"); $sel->wait_for_page_to_load_ok(WAIT_TIME); $sel->title_is("New Field Value Created"); $sel->is_text_present_ok("The value have fun? has been added as a valid choice for the List$bug1_id (cf_qa_list_$bug1_id) field."); + $sel->click_ok("link=Add"); $sel->wait_for_page_to_load_ok(WAIT_TIME); -$sel->title_is("Add Value for the \'List$bug1_id\' (cf_qa_list_$bug1_id) field"); +$sel->title_is("Add Value for the 'List$bug1_id' (cf_qa_list_$bug1_id) field"); $sel->type_ok("value", "storage"); $sel->type_ok("sortkey", "49"); $sel->click_ok("create"); @@ -83,6 +86,65 @@ $sel->wait_for_page_to_load_ok(WAIT_TIME); $sel->title_is("New Field Value Created"); $sel->is_text_present_ok("The value storage has been added as a valid choice for the List$bug1_id (cf_qa_list_$bug1_id) field."); +# Also create a new bug status and a new resolution. + +go_to_admin($sel); +$sel->click_ok("link=Field Values"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Edit values for which field?"); +$sel->click_ok("link=Resolution"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Select value for the 'Resolution' (resolution) field"); +$sel->click_ok("link=Add"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Add Value for the 'Resolution' (resolution) field"); +$sel->type_ok("value", "UPSTREAM"); +$sel->type_ok("sortkey", 450); +$sel->click_ok("create"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("New Field Value Created"); + +go_to_admin($sel); +$sel->click_ok("link=Field Values"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Edit values for which field?"); +$sel->click_ok("link=Status"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Select value for the 'Status' (bug_status) field"); +$sel->click_ok("link=Add"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Add Value for the 'Status' (bug_status) field"); +$sel->type_ok("value", "SUSPENDED"); +$sel->type_ok("sortkey", 250); +$sel->click_ok("open_status"); +$sel->click_ok("create"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("New Field Value Created"); + +$sel->click_ok("link=Add"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Add Value for the 'Status' (bug_status) field"); +$sel->type_ok("value", "IN_QA"); +$sel->type_ok("sortkey", 550); +$sel->click_ok("closed_status"); +$sel->click_ok("create"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("New Field Value Created"); + +$sel->click_ok("link=status workflow page"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Edit Workflow"); +$sel->click_ok('//td[@title="From UNCONFIRMED to SUSPENDED"]//input[@type="checkbox"]'); +$sel->click_ok('//td[@title="From NEW to SUSPENDED"]//input[@type="checkbox"]'); +$sel->click_ok('//td[@title="From SUSPENDED to NEW"]//input[@type="checkbox"]'); +$sel->click_ok('//td[@title="From SUSPENDED to ASSIGNED"]//input[@type="checkbox"]'); +$sel->click_ok('//td[@title="From RESOLVED to IN_QA"]//input[@type="checkbox"]'); +$sel->click_ok('//td[@title="From IN_QA to VERIFIED"]//input[@type="checkbox"]'); +$sel->click_ok('//td[@title="From IN_QA to NEW"]//input[@type="checkbox"]'); +$sel->click_ok('//input[@value="Commit Changes"]'); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Edit Workflow"); + # Create new bug to test custom fields in bug creation page file_bug_in_product($sel, 'TestProduct'); @@ -99,26 +161,39 @@ my $bug2_id = $sel->get_value('//input[@name="id" and @type="hidden"]'); $sel->type_ok("cf_qa_freetext_$bug1_id", "bonsai"); $sel->selected_label_is("cf_qa_list_$bug1_id", "---"); +$sel->select_ok("bug_status", "label=SUSPENDED"); $sel->click_ok("commit"); $sel->wait_for_page_to_load_ok(WAIT_TIME); $sel->title_is("Bug $bug2_id processed"); + $sel->type_ok("quicksearch_top", $bug1_id); $sel->click_ok("find_top"); $sel->wait_for_page_to_load_ok(WAIT_TIME); $sel->title_like(qr/^Bug $bug1_id/); $sel->type_ok("cf_qa_freetext_$bug1_id", "dumbo"); $sel->select_ok("cf_qa_list_$bug1_id", "label=storage"); +$sel->select_ok("bug_status", "RESOLVED"); +$sel->select_ok("resolution", "UPSTREAM"); $sel->click_ok("commit"); $sel->wait_for_page_to_load_ok(WAIT_TIME); $sel->title_is("Bug $bug1_id processed"); $sel->click_ok("link=bug $bug1_id"); $sel->wait_for_page_to_load_ok(WAIT_TIME); $sel->title_like(qr/^Bug $bug1_id/); +$sel->select_ok("bug_status", "IN_QA"); +$sel->click_ok("commit"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_is("Bug $bug1_id processed"); +$sel->click_ok("link=bug $bug1_id"); +$sel->wait_for_page_to_load_ok(WAIT_TIME); +$sel->title_like(qr/^Bug $bug1_id/); + $sel->click_ok("link=Format For Printing"); $sel->wait_for_page_to_load_ok(WAIT_TIME); $sel->title_is("Full Text Bug Listing"); $sel->is_text_present_ok("Freetext$bug1_id: dumbo"); $sel->is_text_present_ok("List$bug1_id: storage"); +$sel->is_text_present_ok("Status: IN_QA UPSTREAM"); $sel->type_ok("quicksearch_top", $bug2_id); $sel->click_ok("find_top"); $sel->wait_for_page_to_load_ok(WAIT_TIME); @@ -134,6 +209,7 @@ open_advanced_search_page($sel); $sel->remove_all_selections_ok("product"); $sel->add_selection_ok("product", "TestProduct"); $sel->remove_all_selections("bug_status"); +$sel->remove_all_selections("resolution"); $sel->select_ok("field0-0-0", "label=List$bug1_id"); $sel->select_ok("type0-0-0", "label=is equal to"); $sel->type_ok("value0-0-0", "storage"); @@ -173,10 +249,10 @@ $sel->wait_for_page_to_load_ok(WAIT_TIME); $sel->title_is("Edit values for which field?"); $sel->click_ok("link=List$bug1_id"); $sel->wait_for_page_to_load_ok(WAIT_TIME); -$sel->title_is("Select value for the \'List$bug1_id\' (cf_qa_list_$bug1_id) field"); +$sel->title_is("Select value for the 'List$bug1_id' (cf_qa_list_$bug1_id) field"); $sel->click_ok("//a[contains(\@href, 'editvalues.cgi?action=del&field=cf_qa_list_$bug1_id&value=have%20fun%3F')]"); $sel->wait_for_page_to_load_ok(WAIT_TIME); -$sel->title_is("Delete Value \'have fun?\' from the \'List$bug1_id\' (cf_qa_list_$bug1_id) field"); +$sel->title_is("Delete Value 'have fun?' from the 'List$bug1_id' (cf_qa_list_$bug1_id) field"); $sel->is_text_present_ok("Do you really want to delete this value?"); $sel->click_ok("delete"); $sel->wait_for_page_to_load_ok(WAIT_TIME); @@ -186,7 +262,7 @@ $sel->title_is("Field Value Deleted"); $sel->click_ok("//a[contains(\@href, 'editvalues.cgi?action=del&field=cf_qa_list_$bug1_id&value=storage')]"); $sel->wait_for_page_to_load_ok(WAIT_TIME); -$sel->title_is("Delete Value \'storage\' from the \'List$bug1_id\' (cf_qa_list_$bug1_id) field"); +$sel->title_is("Delete Value 'storage' from the 'List$bug1_id' (cf_qa_list_$bug1_id) field"); $sel->is_text_present_ok("There is 1 bug with this field value"); # Mark the