updated core to 8.6.3
This commit is contained in:
@@ -0,0 +1,130 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\FunctionalJavascriptTests\Ajax;
|
||||
|
||||
use Drupal\FunctionalJavascriptTests\WebDriverTestBase;
|
||||
|
||||
/**
|
||||
* Performs tests on AJAX framework commands.
|
||||
*
|
||||
* @group Ajax
|
||||
*/
|
||||
class CommandsTest extends WebDriverTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['node', 'ajax_test', 'ajax_forms_test'];
|
||||
|
||||
/**
|
||||
* Tests the various Ajax Commands.
|
||||
*/
|
||||
public function testAjaxCommands() {
|
||||
$session = $this->getSession();
|
||||
$page = $this->getSession()->getPage();
|
||||
|
||||
$form_path = 'ajax_forms_test_ajax_commands_form';
|
||||
$web_user = $this->drupalCreateUser(['access content']);
|
||||
$this->drupalLogin($web_user);
|
||||
$this->drupalGet($form_path);
|
||||
|
||||
// Tests the 'add_css' command.
|
||||
$page->pressButton("AJAX 'add_css' command");
|
||||
$this->assertWaitPageContains('my/file.css');
|
||||
|
||||
// Tests the 'after' command.
|
||||
$page->pressButton("AJAX 'After': Click to put something after the div");
|
||||
$this->assertWaitPageContains('<div id="after_div">Something can be inserted after this</div>This will be placed after');
|
||||
|
||||
// Tests the 'alert' command.
|
||||
$test_alert_command = <<<JS
|
||||
window.alert = function() {
|
||||
document.body.innerHTML += '<div class="alert-command">Alert</div>';
|
||||
};
|
||||
JS;
|
||||
$session->executeScript($test_alert_command);
|
||||
$page->pressButton("AJAX 'Alert': Click to alert");
|
||||
$this->assertWaitPageContains('<div class="alert-command">Alert</div>');
|
||||
|
||||
// Tests the 'append' command.
|
||||
$page->pressButton("AJAX 'Append': Click to append something");
|
||||
$this->assertWaitPageContains('<div id="append_div">Append inside this divAppended text</div>');
|
||||
|
||||
// Tests the 'before' command.
|
||||
$page->pressButton("AJAX 'before': Click to put something before the div");
|
||||
$this->assertWaitPageContains('Before text<div id="before_div">Insert something before this.</div>');
|
||||
|
||||
// Tests the 'changed' command.
|
||||
$page->pressButton("AJAX changed: Click to mark div changed.");
|
||||
$this->assertWaitPageContains('<div id="changed_div" class="ajax-changed">');
|
||||
|
||||
// Tests the 'changed' command using the second argument.
|
||||
// Refresh page for testing 'changed' command to same element again.
|
||||
$this->drupalGet($form_path);
|
||||
$page->pressButton("AJAX changed: Click to mark div changed with asterisk.");
|
||||
$this->assertWaitPageContains('<div id="changed_div" class="ajax-changed"> <div id="changed_div_mark_this">This div can be marked as changed or not. <abbr class="ajax-changed" title="Changed">*</abbr> </div></div>');
|
||||
|
||||
// Tests the 'css' command.
|
||||
$page->pressButton("Set the '#box' div to be blue.");
|
||||
$this->assertWaitPageContains('<div id="css_div" style="background-color: blue;">');
|
||||
|
||||
// Tests the 'data' command.
|
||||
$page->pressButton("AJAX data command: Issue command.");
|
||||
$this->assertTrue($page->waitFor(10, function () use ($session) {
|
||||
return 'testvalue' === $session->evaluateScript('window.jQuery("#data_div").data("testkey")');
|
||||
}));
|
||||
|
||||
// Tests the 'html' command.
|
||||
$page->pressButton("AJAX html: Replace the HTML in a selector.");
|
||||
$this->assertWaitPageContains('<div id="html_div">replacement text</div>');
|
||||
|
||||
// Tests the 'insert' command.
|
||||
$page->pressButton("AJAX insert: Let client insert based on #ajax['method'].");
|
||||
$this->assertWaitPageContains('<div id="insert_div">insert replacement textOriginal contents</div>');
|
||||
|
||||
// Tests the 'invoke' command.
|
||||
$page->pressButton("AJAX invoke command: Invoke addClass() method.");
|
||||
$this->assertWaitPageContains('<div id="invoke_div" class="error">Original contents</div>');
|
||||
|
||||
// Tests the 'prepend' command.
|
||||
$page->pressButton("AJAX 'prepend': Click to prepend something");
|
||||
$this->assertWaitPageContains('<div id="prepend_div">prepended textSomething will be prepended to this div. </div>');
|
||||
|
||||
// Tests the 'remove' command.
|
||||
$page->pressButton("AJAX 'remove': Click to remove text");
|
||||
$this->assertWaitPageContains('<div id="remove_div"></div>');
|
||||
|
||||
// Tests the 'restripe' command.
|
||||
$page->pressButton("AJAX 'restripe' command");
|
||||
$this->assertWaitPageContains('<tr id="table-first" class="odd"><td>first row</td></tr>');
|
||||
$this->assertWaitPageContains('<tr class="even"><td>second row</td></tr>');
|
||||
|
||||
// Tests the 'settings' command.
|
||||
$test_settings_command = <<<JS
|
||||
Drupal.behaviors.testSettingsCommand = {
|
||||
attach: function (context, settings) {
|
||||
window.jQuery('body').append('<div class="test-settings-command">' + settings.ajax_forms_test.foo + '</div>');
|
||||
}
|
||||
};
|
||||
JS;
|
||||
$session->executeScript($test_settings_command);
|
||||
// @todo: Replace after https://www.drupal.org/project/drupal/issues/2616184
|
||||
$session->executeScript('window.jQuery("#edit-settings-command-example").mousedown();');
|
||||
$this->assertWaitPageContains('<div class="test-settings-command">42</div>');
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that page contains a text after waiting.
|
||||
*
|
||||
* @param string $text
|
||||
* A needle text.
|
||||
*/
|
||||
protected function assertWaitPageContains($text) {
|
||||
$page = $this->getSession()->getPage();
|
||||
$page->waitFor(10, function () use ($page, $text) {
|
||||
return stripos($page->getContent(), $text) !== FALSE;
|
||||
});
|
||||
$this->assertContains($text, $page->getContent());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,167 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\FunctionalJavascriptTests\Ajax;
|
||||
|
||||
use Drupal\ajax_test\Controller\AjaxTestController;
|
||||
use Drupal\Component\Render\FormattableMarkup;
|
||||
use Drupal\FunctionalJavascriptTests\WebDriverTestBase;
|
||||
|
||||
/**
|
||||
* Performs tests on opening and manipulating dialogs via AJAX commands.
|
||||
*
|
||||
* @group Ajax
|
||||
*/
|
||||
class DialogTest extends WebDriverTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $modules = ['ajax_test', 'ajax_forms_test', 'contact'];
|
||||
|
||||
/**
|
||||
* Test sending non-JS and AJAX requests to open and manipulate modals.
|
||||
*/
|
||||
public function testDialog() {
|
||||
$this->drupalLogin($this->drupalCreateUser(['administer contact forms']));
|
||||
// Ensure the elements render without notices or exceptions.
|
||||
$this->drupalGet('ajax-test/dialog');
|
||||
|
||||
// Set up variables for this test.
|
||||
$dialog_renderable = AjaxTestController::dialogContents();
|
||||
$dialog_contents = \Drupal::service('renderer')->renderRoot($dialog_renderable);
|
||||
|
||||
// Check that requesting a modal dialog without JS goes to a page.
|
||||
$this->drupalGet('ajax-test/dialog-contents');
|
||||
$this->assertSession()->responseContains($dialog_contents);
|
||||
|
||||
// Visit the page containing the many test dialog links.
|
||||
$this->drupalGet('ajax-test/dialog');
|
||||
|
||||
// Tests a basic modal dialog by verifying the contents of the dialog are as
|
||||
// expected.
|
||||
$this->getSession()->getPage()->clickLink('Link 1 (modal)');
|
||||
|
||||
// Clicking the link triggers a AJAX request/response.
|
||||
// Opens a Dialog panel.
|
||||
$link1_dialog_div = $this->assertSession()->waitForElementVisible('css', 'div.ui-dialog');
|
||||
$this->assertNotNull($link1_dialog_div, 'Link was used to open a dialog ( modal )');
|
||||
|
||||
$link1_modal = $link1_dialog_div->find('css', '#drupal-modal');
|
||||
$this->assertNotNull($link1_modal, 'Link was used to open a dialog ( non-modal )');
|
||||
$this->assertSession()->responseContains($dialog_contents);
|
||||
|
||||
$dialog_title = $link1_dialog_div->find('css', "span.ui-dialog-title:contains('AJAX Dialog & contents')");
|
||||
$this->assertNotNull($dialog_title);
|
||||
$dialog_title_amp = $link1_dialog_div->find('css', "span.ui-dialog-title:contains('AJAX Dialog & contents')");
|
||||
$this->assertNull($dialog_title_amp);
|
||||
|
||||
// Close open dialog, return to the dialog links page.
|
||||
$close_button = $link1_dialog_div->findButton('Close');
|
||||
$this->assertNotNull($close_button);
|
||||
$close_button->press();
|
||||
|
||||
// Tests a modal with a dialog-option.
|
||||
// Link 2 is similar to Link 1, except it submits additional width
|
||||
// information which must be echoed in the resulting DOM update.
|
||||
$this->getSession()->getPage()->clickLink('Link 2 (modal)');
|
||||
$dialog = $this->assertSession()->waitForElementVisible('css', 'div.ui-dialog');
|
||||
$this->assertNotNull($dialog, 'Link was used to open a dialog ( non-modal, with options )');
|
||||
$style = $dialog->getAttribute('style');
|
||||
$this->assertContains('width: 400px;', $style, new FormattableMarkup('Modal respected the dialog-options width parameter. Style = style', ['%style' => $style]));
|
||||
|
||||
// Reset: Return to the dialog links page.
|
||||
$this->drupalGet('ajax-test/dialog');
|
||||
|
||||
// Test a non-modal dialog ( with target ).
|
||||
$this->clickLink('Link 3 (non-modal)');
|
||||
$non_modal_dialog = $this->assertSession()->waitForElementVisible('css', 'div.ui-dialog');
|
||||
$this->assertNotNull($non_modal_dialog, 'Link opens a non-modal dialog.');
|
||||
|
||||
// Tests the dialog contains a target element specified in the AJAX request.
|
||||
$non_modal_dialog->find('css', 'div#ajax-test-dialog-wrapper-1');
|
||||
$this->assertSession()->responseContains($dialog_contents);
|
||||
|
||||
// Reset: Return to the dialog links page.
|
||||
$this->drupalGet('ajax-test/dialog');
|
||||
|
||||
// Tests a non-modal dialog ( without target ).
|
||||
$this->clickLink('Link 7 (non-modal, no target)');
|
||||
$no_target_dialog = $this->assertSession()->waitForElementVisible('css', 'div.ui-dialog');
|
||||
$this->assertNotNull($no_target_dialog, 'Link opens a non-modal dialog.');
|
||||
|
||||
$contents_no_target = $no_target_dialog->find('css', 'div.ui-dialog-content');
|
||||
$this->assertNotNull($contents_no_target, 'non-modal dialog opens ( no target ). ');
|
||||
$id = $contents_no_target->getAttribute('id');
|
||||
$partial_match = strpos($id, 'drupal-dialog-ajax-testdialog-contents') === 0;
|
||||
$this->assertTrue($partial_match, 'The non-modal ID has the expected prefix.');
|
||||
|
||||
$no_target_button = $no_target_dialog->findButton('Close');
|
||||
$this->assertNotNull($no_target_button, 'Link dialog has a close button');
|
||||
$no_target_button->press();
|
||||
|
||||
$this->getSession()->getPage()->findButton('Button 1 (modal)')->press();
|
||||
$button1_dialog = $this->assertSession()->waitForElementVisible('css', 'div.ui-dialog');
|
||||
$this->assertNotNull($button1_dialog, 'Button opens a modal dialog.');
|
||||
|
||||
$button1_dialog_content = $button1_dialog->find('css', 'div.ui-dialog-content');
|
||||
$this->assertNotNull($button1_dialog_content, 'Button opens a modal dialog.');
|
||||
|
||||
// Test the HTML escaping of & character.
|
||||
$button1_dialog_title = $button1_dialog->find('css', "span.ui-dialog-title:contains('AJAX Dialog & contents')");
|
||||
$this->assertNotNull($button1_dialog_title);
|
||||
$button1_dialog_title_amp = $button1_dialog->find('css', "span.ui-dialog-title:contains('AJAX Dialog & contents')");
|
||||
$this->assertNull($button1_dialog_title_amp);
|
||||
|
||||
// Reset: Close the dialog.
|
||||
$button1_dialog->findButton('Close')->press();
|
||||
|
||||
// Abbreviated test for "normal" dialogs, testing only the difference.
|
||||
$this->getSession()->getPage()->findButton('Button 2 (non-modal)')->press();
|
||||
$button2_dialog = $this->assertSession()->waitForElementVisible('css', 'div.ui-dialog-content');
|
||||
$this->assertNotNull($button2_dialog, 'Non-modal content displays as expected.');
|
||||
|
||||
// Use a link to close the pagnel opened by button 2.
|
||||
$this->getSession()->getPage()->clickLink('Link 4 (close non-modal if open)');
|
||||
|
||||
// Form modal.
|
||||
$this->clickLink('Link 5 (form)');
|
||||
// Two links have been clicked in succession - This time wait for a change
|
||||
// in the title as the previous closing dialog may temporarily be open.
|
||||
$form_dialog_title = $this->assertSession()->waitForElementVisible('css', "span.ui-dialog-title:contains('Ajax Form contents')");
|
||||
$this->assertNotNull($form_dialog_title, 'Dialog form has the expected title.');
|
||||
// Locate the newly opened dialog.
|
||||
$form_dialog = $this->getSession()->getPage()->find('css', 'div.ui-dialog');
|
||||
$this->assertNotNull($form_dialog, 'Form dialog is visible');
|
||||
|
||||
$form_contents = $form_dialog->find('css', "p:contains('Ajax Form contents description.')");
|
||||
$this->assertNotNull($form_contents, 'For has the expected text.');
|
||||
$do_it = $form_dialog->findButton('Do it');
|
||||
$this->assertNotNull($do_it, 'The dialog has a "Do it" button.');
|
||||
$preview = $form_dialog->findButton('Preview');
|
||||
$this->assertNotNull($preview, 'The dialog contains a "Preview" button.');
|
||||
|
||||
// Reset: close the form.
|
||||
$form_dialog->findButton('Close')->press();
|
||||
|
||||
// Non AJAX version of Link 6.
|
||||
$this->drupalGet('admin/structure/contact/add');
|
||||
// Check we get a chunk of the code, we can't test the whole form as form
|
||||
// build id and token with be different.
|
||||
$contact_form = $this->xpath("//form[@id='contact-form-add-form']");
|
||||
$this->assertTrue(!empty($contact_form), 'Non-JS entity form page present.');
|
||||
|
||||
// Reset: Return to the dialog links page.
|
||||
$this->drupalGet('ajax-test/dialog');
|
||||
|
||||
$this->clickLink('Link 6 (entity form)');
|
||||
$dialog_add = $this->assertSession()->waitForElementVisible('css', 'div.ui-dialog');
|
||||
$this->assertNotNull($dialog_add, 'Form dialog is visible');
|
||||
|
||||
$form_add = $dialog_add->find('css', 'form.contact-form-add-form');
|
||||
$this->assertNotNull($form_add, 'Modal dialog JSON contains entity form.');
|
||||
|
||||
$form_title = $dialog_add->find('css', "span.ui-dialog-title:contains('Add contact form')");
|
||||
$this->assertNotNull($form_title, 'The add form title is as expected.');
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,139 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\FunctionalJavascriptTests\Ajax;
|
||||
|
||||
use Drupal\Component\Render\FormattableMarkup;
|
||||
use Drupal\Core\Field\FieldStorageDefinitionInterface;
|
||||
use Drupal\field\Entity\FieldConfig;
|
||||
use Drupal\field\Entity\FieldStorageConfig;
|
||||
use Drupal\FunctionalJavascriptTests\WebDriverTestBase;
|
||||
|
||||
/**
|
||||
* Tests that AJAX-enabled forms work when multiple instances of the same form
|
||||
* are on a page.
|
||||
*
|
||||
* @group Ajax
|
||||
*/
|
||||
class MultiFormTest extends WebDriverTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['node', 'form_test'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
$this->drupalCreateContentType(['type' => 'page', 'name' => 'Page']);
|
||||
|
||||
// Create a multi-valued field for 'page' nodes to use for Ajax testing.
|
||||
$field_name = 'field_ajax_test';
|
||||
FieldStorageConfig::create([
|
||||
'entity_type' => 'node',
|
||||
'field_name' => $field_name,
|
||||
'type' => 'text',
|
||||
'cardinality' => FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED,
|
||||
])->save();
|
||||
FieldConfig::create([
|
||||
'field_name' => $field_name,
|
||||
'entity_type' => 'node',
|
||||
'bundle' => 'page',
|
||||
])->save();
|
||||
entity_get_form_display('node', 'page', 'default')
|
||||
->setComponent($field_name, ['type' => 'text_textfield'])
|
||||
->save();
|
||||
|
||||
// Log in a user who can create 'page' nodes.
|
||||
$this->drupalLogin($this->drupalCreateUser(['create page content']));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that pages with the 'node_page_form' included twice work correctly.
|
||||
*/
|
||||
public function testMultiForm() {
|
||||
// HTML IDs for elements within the field are potentially modified with
|
||||
// each Ajax submission, but these variables are stable and help target the
|
||||
// desired elements.
|
||||
$field_name = 'field_ajax_test';
|
||||
|
||||
$form_xpath = '//form[starts-with(@id, "node-page-form")]';
|
||||
$field_xpath = '//div[contains(@class, "field--name-field-ajax-test")]';
|
||||
$button_name = $field_name . '_add_more';
|
||||
$button_value = t('Add another item');
|
||||
$button_xpath_suffix = '//input[@name="' . $button_name . '"]';
|
||||
$field_items_xpath_suffix = '//input[@type="text"]';
|
||||
|
||||
// Ensure the initial page contains both node forms and the correct number
|
||||
// of field items and "add more" button for the multi-valued field within
|
||||
// each form.
|
||||
$this->drupalGet('form-test/two-instances-of-same-form');
|
||||
|
||||
// Wait for javascript on the page to prepare the form attributes.
|
||||
$this->assertSession()->assertWaitOnAjaxRequest();
|
||||
|
||||
$session = $this->getSession();
|
||||
$page = $session->getPage();
|
||||
$fields = $page->findAll('xpath', $form_xpath . $field_xpath);
|
||||
$this->assertEqual(count($fields), 2);
|
||||
foreach ($fields as $field) {
|
||||
$this->assertCount(1, $field->findAll('xpath', '.' . $field_items_xpath_suffix), 'Found the correct number of field items on the initial page.');
|
||||
$this->assertFieldsByValue($field->find('xpath', '.' . $button_xpath_suffix), NULL, 'Found the "add more" button on the initial page.');
|
||||
}
|
||||
|
||||
$this->assertNoDuplicateIds();
|
||||
|
||||
// Submit the "add more" button of each form twice. After each corresponding
|
||||
// page update, ensure the same as above.
|
||||
|
||||
for ($i = 0; $i < 2; $i++) {
|
||||
$forms = $page->find('xpath', $form_xpath);
|
||||
foreach ($forms as $offset => $form) {
|
||||
$button = $form->findButton($button_value);
|
||||
$this->assertNotNull($button, 'Add Another Item button exists');
|
||||
$button->press();
|
||||
|
||||
// Wait for page update.
|
||||
$this->assertSession()->assertWaitOnAjaxRequest();
|
||||
|
||||
// After AJAX request and response page will update.
|
||||
$page_updated = $session->getPage();
|
||||
$field = $page_updated->findAll('xpath', '.' . $field_xpath);
|
||||
$this->assertEqual(count($field[0]->find('xpath', '.' . $field_items_xpath_suffix)), $i + 2, 'Found the correct number of field items after an AJAX submission.');
|
||||
$this->assertFieldsByValue($field[0]->find('xpath', '.' . $button_xpath_suffix), NULL, 'Found the "add more" button after an AJAX submission.');
|
||||
$this->assertNoDuplicateIds();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that each HTML ID is used for just a single element on the page.
|
||||
*
|
||||
* @param string $message
|
||||
* (optional) A message to display with the assertion.
|
||||
*/
|
||||
protected function assertNoDuplicateIds($message = '') {
|
||||
$args = ['@url' => $this->getUrl()];
|
||||
|
||||
if (!$elements = $this->xpath('//*[@id]')) {
|
||||
$this->fail(new FormattableMarkup('The page @url contains no HTML IDs.', $args));
|
||||
return;
|
||||
}
|
||||
|
||||
$message = $message ?: new FormattableMarkup('The page @url does not contain duplicate HTML IDs', $args);
|
||||
|
||||
$seen_ids = [];
|
||||
foreach ($elements as $element) {
|
||||
$id = $element->getAttribute('id');
|
||||
if (isset($seen_ids[$id])) {
|
||||
$this->fail($message);
|
||||
return;
|
||||
}
|
||||
$seen_ids[$id] = TRUE;
|
||||
}
|
||||
$this->assertTrue(TRUE, $message);
|
||||
}
|
||||
|
||||
}
|
||||
+1
-1
@@ -2,10 +2,10 @@
|
||||
|
||||
namespace Drupal\FunctionalJavascriptTests\EntityReference;
|
||||
|
||||
use Drupal\field\Tests\EntityReference\EntityReferenceTestTrait;
|
||||
use Drupal\FunctionalJavascriptTests\WebDriverTestBase;
|
||||
use Drupal\simpletest\ContentTypeCreationTrait;
|
||||
use Drupal\simpletest\NodeCreationTrait;
|
||||
use Drupal\Tests\field\Traits\EntityReferenceTestTrait;
|
||||
|
||||
/**
|
||||
* Tests the output of entity reference autocomplete widgets.
|
||||
|
||||
Reference in New Issue
Block a user