2

I'm trying to build out a SimpleTest to test out functionality on submitted webforms. I need to simulate loading a drupal webform node, applying fake data, and submitting the form (triggering a database save).

Currently, I'm forcing data in (on a vagrant box) a drupal instance, but I have a feeling there is a better way to do this.

Question: In Simpletest, how do I properly load a webform, inject fake data into the form fields, and submit the form?

First attemtp: Original fixture code. It works, but it's sloppy!

Class myTest extends DrupalWebTestCase {
.
.
.
  /*
  Drops ALL DATA in the tables being tested
  */
  function _dropData() {
     db_query('delete from {webform_submitted_data}');
     db_query('delete from {webform_submissions}');
  }

  /*
  Fixtures, test data. Clears both webform_submitted_data and webform_submissions
  and then adds a new set of mock data generated initially by a browser plugin
  that autofills forms. This allows for a standardized set of data used on the
  simple test form (import script included in the package).
  */
  function _populateTablesWithTestData() {
    $q1 = "SET SQL_MODE = \"NO_AUTO_VALUE_ON_ZERO\"; INSERT INTO `webform_submitted_data` (`nid`, `sid`, `cid`, `no`, `data`) VALUES (1, 59, 2, '0', 'Dignissimos enim dolorem quia et minim velit eiusmod eiusmod voluptas nemo nostrum cum aliquam unde mollit obcaecati'), (1, 59, 3, '0', 'pugy@example.com'), (1, 59, 4, '0', '2013-03-11'), (1, 60, 2, '0', 'Sapiente velit voluptatem et quod et proident voluptatem Sunt minima reprehenderit reprehenderit'),(1, 60, 3, '0', 'nejemuno@example.com'),(1, 60, 4, '0', '2014-05-16'),(1, 61, 2, '0', 'Id nisi pariatur Quidem in nihil culpa qui rerum minim nihil ea minim ipsa fugiat'),(1, 61, 3, '0', 'mohafowoba@example.com'),(1, 61, 4, '0', '2015-05-02'),(1, 62, 2, '0', 'Omnis quisquam nisi non et est est eiusmod qui qui odio ut dignissimos'),(1, 62, 3, '0', 'vujil@example.com'),(1, 62, 4, '0', '2015-03-02');";
    $q2 = "SET SQL_MODE = \"NO_AUTO_VALUE_ON_ZERO\"; INSERT INTO `webform_submissions` (`sid`, `nid`, `serial`, `uid`, `is_draft`, `submitted`, `remote_addr`) VALUES (59, 1, 59, 0, 0, 1424275998, '192.168.33.1'), (60, 1, 60, 0, 0, 1424276006, '192.168.33.1'), (61, 1, 61, 0, 0, 1424276013, '192.168.33.1'), (62, 1, 62, 0, 0, 1424276031, '192.168.33.1');";

    $this->_dropData();
    db_query($q1);
    db_query($q2);
  }

Second Attempt:

In a test script to be run from drush...

$form_state = array();
$form_state['values']['test2']='Something';
$form_state['values']['test_email']='Some@email.ext';
$form_state['values']['test_date']="";

drupal_form_submit('webform_client_form_1', $form_state);

However, this gives me:

$ drush scr test.php

Missing argument 3 for webform_client_form() webform.module:2268                                                               [warning]
Invalid argument supplied for foreach() webform.module:2843   

Third Attempt

$form_state = array();
$form_state['values']['test2']='Something';
$form_state['values']['test_email']='Some@email.ext';
$form_state['values']['test_date']="";
$form_state['op'] = t('Submit');


drupal_form_submit('webform_client_form_1', $form_state, node_load(1), array());
print_r(form_get_errors());

Which gets:

$drush scr test.php

end() expects parameter 1 to be array, null given webform.module:3120                                                          [warning]
end() expects parameter 1 to be array, null given webform.module:3123  

What the form looks like

Export Code:

$webform = array (
  'nid' => '1',
  'next_serial' => '63',
  'confirmation' => '',
  'confirmation_format' => 'filtered_html',
  'redirect_url' => '<confirmation>',
  'status' => '1',
  'block' => '0',
  'allow_draft' => '0',
  'auto_save' => '0',
  'submit_notice' => '1',
  'submit_text' => '',
  'submit_limit' => '-1',
  'submit_interval' => '-1',
  'total_submit_limit' => '-1',
  'total_submit_interval' => '-1',
  'progressbar_bar' => '1',
  'progressbar_page_number' => '0',
  'progressbar_percent' => '0',
  'progressbar_pagebreak_labels' => '1',
  'progressbar_include_confirmation' => '1',
  'progressbar_label_first' => 'Start',
  'progressbar_label_confirmation' => 'Complete',
  'preview' => '0',
  'preview_next_button_label' => '',
  'preview_prev_button_label' => '',
  'preview_title' => '',
  'preview_message' => '',
  'preview_message_format' => 'filtered_html',
  'preview_excluded_components' => 
  array (
  ),
  'record_exists' => true,
  'roles' => 
  array (
    0 => '1',
    1 => '2',
  ),
  'emails' => 
  array (
  ),
  'components' => 
  array (
    2 => 
    array (
      'nid' => 1,
      'cid' => '2',
      'pid' => '0',
      'form_key' => 'test2',
      'name' => 'TEST Text ',
      'type' => 'textfield',
      'value' => '',
      'extra' => 
      array (
        'title_display' => 'before',
        'private' => 0,
        'wrapper_classes' => '',
        'css_classes' => '',
        'width' => '',
        'maxlength' => '',
        'field_prefix' => '',
        'field_suffix' => '',
        'disabled' => 0,
        'unique' => 0,
        'description' => '',
        'placeholder' => '',
        'attributes' => 
        array (
        ),
        'analysis' => false,
      ),
      'required' => '0',
      'weight' => '1',
      'page_num' => 1,
    ),
    3 => 
    array (
      'nid' => 1,
      'cid' => '3',
      'pid' => '0',
      'form_key' => 'test_email',
      'name' => 'TEst Email',
      'type' => 'email',
      'value' => '',
      'extra' => 
      array (
        'title_display' => 'before',
        'private' => 0,
        'wrapper_classes' => '',
        'css_classes' => '',
        'width' => '',
        'unique' => 0,
        'disabled' => 0,
        'description' => '',
        'placeholder' => '',
        'attributes' => 
        array (
        ),
        'analysis' => false,
      ),
      'required' => '0',
      'weight' => '2',
      'page_num' => 1,
    ),
    4 => 
    array (
      'nid' => 1,
      'cid' => '4',
      'pid' => '0',
      'form_key' => 'date',
      'name' => 'Date',
      'type' => 'date',
      'value' => '',
      'extra' => 
      array (
        'title_display' => 'before',
        'private' => 0,
        'wrapper_classes' => '',
        'timezone' => 'user',
        'start_date' => '-2 years',
        'end_date' => '+2 years',
        'year_textfield' => 0,
        'datepicker' => 1,
        'description' => '',
        'analysis' => false,
      ),
      'required' => '0',
      'weight' => '4',
      'page_num' => 1,
    ),
  ),
  'conditionals' => 
  array (
  ),
);

Screenshot: enter image description here

1
+50

Following code will submit webform programmability

$node_web = node_load(<WEBFORM NODE ID>);
        $data = array(
            1 => array( '<COMPONENT 1 VALUE>'),
            2 => array('<COMPONENT 2 VALUE>'),
        );
        $submission = (object) array(
            'nid' => $node_web->nid,
            'uid' => $user->uid,
            'submitted' => REQUEST_TIME,
            'remote_addr' => ip_address(),
            'is_draft' => FALSE,
            'data' => $data,
            'serial' => _webform_service_submission_serial_next_value($node_web->nid)
        );
        module_load_include('inc', 'webform', 'includes/webform.submissions');
        webform_submission_insert($node_web, $submission);
        webform_submission_send_mail($node_web, $submission); 

Add the _webform_service_submission_serial_next_value function ....

 function _webform_service_submission_serial_next_value($nid, $do_increment = TRUE) {
        if ($do_increment) {
            db_transaction();
        }
        $next_serial = db_select('webform', 'w')
        ->forUpdate()
        ->fields('w', array('next_serial'))
        ->condition('nid', $nid)
        ->execute()
        ->fetchField();

        if ($next_serial && $do_increment) {
            $increment_amount = 1;
            db_update('webform')
            ->fields(array('next_serial' => $next_serial + $increment_amount))
            ->condition('nid', $nid)
            ->execute();
        }
        return $next_serial;
}

Hope this will help...

|improve this answer|||||
  • WOW. This was basically a copy and paste operation. I cannot thank you enough for this. I threw this into a test file, ran by drush scr test.php, and bam, the webform results tab has another entry. Bounty rewarded. – Rick Mar 3 '15 at 16:57
  • I've gotten this to work inside of stright PHP via drush scr test.php but the SimpleTest itself is spitting back errors. drupal.stackexchange.com/questions/150360 – Rick Mar 3 '15 at 22:03
1

You can programatically submit a Drupal form with drupal_form_submit() by passing it a $form_state array with its values sub-array pre-populated with the data you want to submit. You'll need the form id of the form you're submitting, too, which in the case of a Webform is webform_client_form_<NODEID> (of course, replace <NODEID> with the node ID of the webform you want to submit).

|improve this answer|||||
  • I've added the results of doing this in the question above. Basically, I get "Missing argument 3 for webform_client_form() webform.module: 2268 [warning] Invalid argument supplied for foreach() webform.module:2843" – Rick Mar 2 '15 at 20:40
  • 1
    I see you got past that, but have another error. But think you're getting close (disclaimer: I've never done this, I just threw my answer out here since I've used drupal_form_submit for non webform-related purposes and figured it would work here). Try nesting your submitted values in another sub-array, $form_state['values']['submitted']. That's the way Webform handles its fields, so maybe your submission isn't passing validation. FWIW, somebody else has gotten this to work: drupal.stackexchange.com/questions/76865/…. – dblue Mar 2 '15 at 23:29
  • Thanks. Although another answer provided a good course, I upvoted your answer for not only pointing me in a good direction but staying in the conversation. Many, many thanks. Upvote. – Rick Mar 3 '15 at 17:00
  • You're welcome, and good to know you got a working solution. Cheers! – dblue Mar 4 '15 at 1:32
0

For building automated tests you should used SeleniumHQ.

|improve this answer|||||
  • For front end, yes. However, I need to test specific actions inside the database. This is also an exercise in learning how to properly set up a SimpleTest in Drupal for module development. – Rick Feb 18 '15 at 19:38
  • Have you hear about the Coder module ? – itsdarrylnorris Feb 18 '15 at 19:41
  • I've used Coder, which is great at syntax checking and best practices in coding convention. My real hope is to learn how to create webform content in order to use in server side automated testing. – Rick Feb 26 '15 at 18:01

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.