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', '[email protected]'), (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', '[email protected]'),(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', '[email protected]'),(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', '[email protected]'),(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']='[email protected]';
$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']='[email protected]';
$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

10

2 Answers 2

1
+50

To programmatically submit a webform, you can use the following code.

global $user;

$node = node_load($nid);
$data = array(
  1 => array( $component1_value),
  2 => array($component2_value),
);

$submission = (object) array(
  'nid' => $node->nid,
  'uid' => $user->uid,
  'submitted' => REQUEST_TIME,
  'remote_addr' => ip_address(),
  'is_draft' => FALSE,
  'data' => $data,
  'serial' => _webform_service_submission_serial_next_value($node->nid)
);

module_load_include('inc', 'webform', 'includes/webform.submissions');
webform_submission_insert($node, $submission);
webform_submission_send_mail($node, $submission); 

function _webform_service_submission_serial_next_value($nid, $increment = TRUE) {
  if ($increment) {
    db_transaction();
  }
  $next_serial = db_select('webform', 'w')
    ->forUpdate()
    ->fields('w', array('next_serial'))
    ->condition('nid', $nid)
    ->execute()
    ->fetchField();
        
  if ($next_serial && $increment) {
    $increment_amount = 1;
    db_update('webform')->fields(array('next_serial' => $next_serial + $increment_amount))
      ->condition('nid', $nid)
      ->execute();
  }
  return $next_serial;
}
2
  • 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, 2015 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, 2015 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).

4
  • 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, 2015 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, 2015 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, 2015 at 17:00
  • You're welcome, and good to know you got a working solution. Cheers!
    – dblue
    Mar 4, 2015 at 1:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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