class ComplexWidgetTest in Inline Entity Form 8
IEF complex field widget tests.
@group inline_entity_form
Hierarchy
- class \Drupal\Tests\BrowserTestBase extends \PHPUnit\Framework\TestCase uses FunctionalTestSetupTrait, TestSetupTrait, AssertLegacyTrait, BlockCreationTrait, ConfigTestTrait, ContentTypeCreationTrait, NodeCreationTrait, PhpunitCompatibilityTrait, RandomGeneratorTrait, TestRequirementsTrait, UiHelperTrait, UserCreationTrait, XdebugRequestTrait
- class \Drupal\FunctionalJavascriptTests\WebDriverTestBase
- class \Drupal\Tests\inline_entity_form\FunctionalJavascript\InlineEntityFormTestBase
- class \Drupal\Tests\inline_entity_form\FunctionalJavascript\ComplexWidgetTest uses TestFileCreationTrait
- class \Drupal\Tests\inline_entity_form\FunctionalJavascript\InlineEntityFormTestBase
- class \Drupal\FunctionalJavascriptTests\WebDriverTestBase
Expanded class hierarchy of ComplexWidgetTest
File
- tests/
src/ FunctionalJavascript/ ComplexWidgetTest.php, line 15
Namespace
Drupal\Tests\inline_entity_form\FunctionalJavascriptView source
class ComplexWidgetTest extends InlineEntityFormTestBase {
use TestFileCreationTrait {
getTestFiles as drupalGetTestFiles;
}
/**
* Modules to enable.
*
* @var array
*/
protected static $modules = [
'inline_entity_form_test',
'field',
'field_ui',
];
/**
* URL to add new content.
*
* @var string
*/
protected $formContentAddUrl;
/**
* Entity form display storage.
*
* @var \Drupal\Core\Config\Entity\ConfigEntityStorageInterface
*/
protected $entityFormDisplayStorage;
/**
* {@inheritdoc}
*/
protected function setUp() : void {
parent::setUp();
$this->user = $this
->createUser([
'create ief_reference_type content',
'create ief_test_nested1 content',
'create ief_test_nested2 content',
'create ief_test_nested3 content',
'edit any ief_reference_type content',
'delete any ief_reference_type content',
'create ief_test_complex content',
'edit any ief_test_complex content',
'delete any ief_test_complex content',
'edit any ief_test_nested1 content',
'edit any ief_test_nested2 content',
'edit any ief_test_nested3 content',
'view own unpublished content',
'administer content types',
]);
$this
->drupalLogin($this->user);
$this->formContentAddUrl = 'node/add/ief_test_complex';
$this->entityFormDisplayStorage = $this->container
->get('entity_type.manager')
->getStorage('entity_form_display');
}
/**
* Tests if form behaves correctly when field is empty.
*/
public function testEmptyField() {
// Get the xpath selectors for the input fields in this test.
$inner_title_field_xpath = $this
->getXpathForNthInputByLabelText('Title', 2);
$first_name_field_xpath = $this
->getXpathForNthInputByLabelText('First name', 1);
$last_name_field_xpath = $this
->getXpathForNthInputByLabelText('Last name', 1);
// Get the xpath selectors for the fieldset labels in this test.
$fieldset_label_all_bundles_xpath = $this
->getXpathForFieldsetLabel('All bundles', 1);
$fieldset_label_multi_xpath = $this
->getXpathForFieldsetLabel('Multiple nodes', 1);
$assert_session = $this
->assertSession();
// Don't allow addition of existing nodes.
$this
->updateSetting('allow_existing', FALSE);
$this
->drupalGet($this->formContentAddUrl);
// Assert fieldset title on inline form exists.
$assert_session
->elementExists('xpath', $fieldset_label_all_bundles_xpath);
$assert_session
->elementExists('xpath', $fieldset_label_multi_xpath);
// Assert title field on inline form exists.
$assert_session
->elementExists('xpath', $inner_title_field_xpath);
// Assert first name field on inline form exists.
$assert_session
->elementExists('xpath', $first_name_field_xpath);
// Assert last name field on inline form exists.
$assert_session
->elementExists('xpath', $last_name_field_xpath);
$assert_session
->buttonExists('Create node');
// Allow addition of existing nodes.
$this
->updateSetting('allow_existing', TRUE);
// Asserts 'Add new node' form elements.
$this
->drupalGet($this->formContentAddUrl);
$multi_fieldset = $assert_session
->elementExists('css', 'fieldset[data-drupal-selector="edit-multi"]');
// Assert fieldset titles.
$assert_session
->elementExists('xpath', $fieldset_label_multi_xpath);
// Assert title field does not appear.
$assert_session
->elementNotExists('xpath', $inner_title_field_xpath);
// Assert first name field does not appear.
$assert_session
->elementNotExists('xpath', $first_name_field_xpath);
// Assert last name field does not appear.
$assert_session
->elementNotExists('xpath', $last_name_field_xpath);
$assert_session
->buttonExists('Add existing node', $multi_fieldset);
// Now submit 'Add new node' button in the 'Multiple nodes' fieldset.
$multi_fieldset
->pressButton('Add new node');
// Assert fieldset title.
$assert_session
->elementExists('xpath', $fieldset_label_multi_xpath);
// Assert title field on inline form exists.
$this
->assertNotEmpty($assert_session
->waitForElement('xpath', $inner_title_field_xpath));
// Assert first name field on inline form exists.
$assert_session
->elementExists('xpath', $first_name_field_xpath);
// Assert second name field on inline form exists.
$assert_session
->elementExists('xpath', $last_name_field_xpath);
$assert_session
->buttonExists('Create node');
$assert_session
->buttonExists('Cancel');
// Asserts 'Add existing node' form elements.
$this
->drupalGet($this->formContentAddUrl);
$multi_fieldset = $assert_session
->elementExists('css', 'fieldset[data-drupal-selector="edit-multi"]');
$multi_fieldset
->pressButton('Add existing node');
// Assert existing entity reference autocomplete field appears.
$this
->assertNotEmpty($assert_session
->waitForElement('xpath', $this
->getXpathForAutoCompleteInput()));
$assert_session
->buttonExists('Add node');
$assert_session
->buttonExists('Cancel');
}
/**
* Tests creation of entities.
*/
public function testEntityCreation() {
// Get the xpath selectors for the input fields in this test.
$first_title_field_xpath = $this
->getXpathForNthInputByLabelText('Title', 1);
$inner_title_field_xpath = $this
->getXpathForNthInputByLabelText('Title', 2);
$first_name_field_xpath = $this
->getXpathForNthInputByLabelText('First name', 1);
$last_name_field_xpath = $this
->getXpathForNthInputByLabelText('Last name', 1);
$assert_session = $this
->assertSession();
$page = $this
->getSession()
->getPage();
// Allow addition of existing nodes.
$this
->updateSetting('allow_existing', TRUE);
$this
->drupalGet($this->formContentAddUrl);
$multi_fieldset = $assert_session
->elementExists('css', 'fieldset[data-drupal-selector="edit-multi"]');
$multi_fieldset
->pressButton('Add new node');
$this
->assertNotEmpty($create_node_button = $assert_session
->waitForButton('Create node'));
$create_node_button
->press();
$this
->assertNotEmpty($assert_session
->waitForElement('css', 'div[data-drupal-messages]'));
$assert_session
->pageTextContains('First name field is required.');
$assert_session
->pageTextContains('Last name field is required.');
$assert_session
->pageTextContains('Title field is required.');
// Create ief_reference_type node in IEF.
$this
->drupalGet($this->formContentAddUrl);
$multi_fieldset = $assert_session
->elementExists('css', 'fieldset[data-drupal-selector="edit-multi"]');
$multi_fieldset
->pressButton('Add new node');
$this
->assertNotEmpty($assert_session
->waitForElement('xpath', $inner_title_field_xpath));
$assert_session
->elementExists('xpath', $inner_title_field_xpath)
->setValue('Some reference');
$assert_session
->elementExists('xpath', $first_name_field_xpath)
->setValue('John');
$assert_session
->elementExists('xpath', $last_name_field_xpath)
->setValue('Doe');
$page
->pressButton('Create node');
$this
->assertNotEmpty($assert_session
->waitForElement('css', '.ief-row-entity'));
// Tests if correct fields appear in the table.
$assert_session
->elementTextContains('css', '.ief-row-entity .inline-entity-form-node-label', 'Some reference');
$assert_session
->elementTextContains('css', '.ief-row-entity .inline-entity-form-node-status', 'Published');
// Tests if edit and remove buttons appear.
$multi_fieldset = $assert_session
->elementExists('css', 'fieldset[data-drupal-selector="edit-multi"]');
$assert_session
->buttonExists('Edit', $multi_fieldset);
$assert_session
->buttonExists('Remove', $multi_fieldset);
// Test edit functionality.
$assert_session
->buttonExists('Edit', $multi_fieldset)
->press();
$this
->assertNotEmpty($assert_session
->waitForElement('xpath', $inner_title_field_xpath));
$assert_session
->elementExists('xpath', $inner_title_field_xpath)
->setValue('Some changed reference');
$page
->pressButton('Update node');
$this
->waitForRowByTitle('Some changed reference');
// Tests if correct fields appear in the table.
$assert_session
->elementTextContains('css', '.ief-row-entity .inline-entity-form-node-label', 'Some changed reference');
$assert_session
->elementTextContains('css', '.ief-row-entity .inline-entity-form-node-status', 'Published');
// Tests if edit and remove buttons appear.
$multi_fieldset = $assert_session
->elementExists('css', 'fieldset[data-drupal-selector="edit-multi"]');
$assert_session
->buttonExists('Edit', $multi_fieldset);
$assert_session
->buttonExists('Remove', $multi_fieldset);
// Make sure unrelated AJAX submit doesn't save the referenced entity.
// @todo restore this test.
// @see https://www.drupal.org/project/inline_entity_form/issues/3088453
$assert_session
->elementExists('xpath', $first_title_field_xpath)
->setValue('Some title');
$page
->pressButton('Save');
$assert_session
->pageTextContains('IEF test complex Some title has been created.');
// Checks values of created entities.
$node = $this
->drupalGetNodeByTitle('Some changed reference');
$this
->assertNotEmpty($node, 'Created ief_reference_type node ' . $node
->label());
$this
->assertSame('John', $node
->get('first_name')->value, 'First name in reference node set to John');
$this
->assertSame('Doe', $node
->get('last_name')->value, 'Last name in reference node set to Doe');
$parent_node = $this
->drupalGetNodeByTitle('Some title');
$this
->assertNotEmpty($parent_node, 'Created ief_test_complex node ' . $parent_node
->label());
$this
->assertSame($node
->id(), $parent_node->multi->target_id, 'Reference node id set to ' . $node
->id());
}
/**
* Tests the entity creation with different bundles nested in each other.
*
* Ief_test_nested1 -> ief_test_nested2 -> ief_test_nested3
*/
public function testNestedEntityCreationWithDifferentBundlesAjaxSubmit() {
// Get the xpath selectors for the input fields in this test.
$top_title_field_xpath = $this
->getXpathForNthInputByLabelText('Title', 1);
$nested_title_field_xpath = $this
->getXpathForNthInputByLabelText('Title', 2);
$double_nested_title_field_xpath = $this
->getXpathForNthInputByLabelText('Title', 3);
// Get the xpath selectors for the fieldset labels in this test.
$top_fieldset_label_xpath = $this
->getXpathForFieldsetLabel('Multiple nodes', 1);
$nested_fieldset_label_xpath = $this
->getXpathForFieldsetLabel('Multiple nodes', 2);
$page = $this
->getSession()
->getPage();
$assert_session = $this
->assertSession();
foreach ([
FALSE,
TRUE,
] as $required) {
$this
->setupNestedComplexForm($required);
$assert_session
->elementExists('xpath', $top_fieldset_label_xpath);
$assert_session
->elementExists('xpath', $nested_fieldset_label_xpath);
$required_string = $required ? ' required' : ' unrequired';
$double_nested_title = 'Dream within a dream' . $required_string;
$nested_title = 'Dream' . $required_string;
$top_level_title = 'Reality' . $required_string;
$this
->assertNotEmpty($field = $assert_session
->waitForElement('xpath', $double_nested_title_field_xpath));
$field
->setValue($double_nested_title);
$page
->pressButton('Create node 3');
$this
->waitForRowByTitle($double_nested_title);
// Assert title of second nested node found.
$this
->assertNoNodeByTitle($double_nested_title, 'Second nested entity is not saved yet.');
$assert_session
->elementExists('xpath', $nested_title_field_xpath)
->setValue($nested_title);
$page
->pressButton('Create node 2');
$this
->waitForRowByTitle($nested_title);
$this
->assertNoNodeByTitle($nested_title, 'First nested entity is not saved yet.');
$assert_session
->elementExists('xpath', $top_title_field_xpath)
->setValue($top_level_title);
$page
->pressButton('Save');
$assert_session
->pageTextContains("IEF test nested 1 {$top_level_title} has been created.");
$top_level_node = $this
->drupalGetNodeByTitle($top_level_title);
$this
->assertNotEmpty($top_level_node);
$nested_node = $this
->drupalGetNodeByTitle($nested_title);
$this
->assertNotEmpty($nested_node);
$double_nested_node = $this
->drupalGetNodeByTitle($double_nested_title);
$this
->assertNotEmpty($double_nested_node);
$this
->checkNestedNodes($top_level_node, $nested_node, $double_nested_node);
}
}
/**
* Tests the entity creation with different bundles nested in each other.
*
* Ief_test_nested1 -> ief_test_nested2 -> ief_test_nested3
*/
public function testNestedEntityCreationWithDifferentBundlesNoAjaxSubmit() {
// Get the xpath selectors for the input fields in this test.
$top_title_field_xpath = $this
->getXpathForNthInputByLabelText('Title', 1);
$nested_title_field_xpath = $this
->getXpathForNthInputByLabelText('Title', 2);
$double_nested_title_field_xpath = $this
->getXpathForNthInputByLabelText('Title', 3);
// Get the xpath selectors for the fieldset labels in this test.
$top_fieldset_label_xpath = $this
->getXpathForFieldsetLabel('Multiple nodes', 1);
$nested_fieldset_label_xpath = $this
->getXpathForFieldsetLabel('Multiple nodes', 2);
$page = $this
->getSession()
->getPage();
$assert_session = $this
->assertSession();
foreach ([
FALSE,
TRUE,
] as $required) {
$this
->setupNestedComplexForm($required);
$assert_session
->elementExists('xpath', $top_fieldset_label_xpath);
$assert_session
->elementExists('xpath', $nested_fieldset_label_xpath);
$required_string = $required ? ' required' : ' unrequired';
$double_nested_title = 'Dream within a dream' . $required_string;
$nested_title = 'Dream' . $required_string;
$top_level_title = 'Reality' . $required_string;
$assert_session
->elementExists('xpath', $top_title_field_xpath)
->setValue($top_level_title);
$assert_session
->elementExists('xpath', $nested_title_field_xpath)
->setValue($nested_title);
$assert_session
->elementExists('xpath', $double_nested_title_field_xpath)
->setValue($double_nested_title);
$page
->pressButton('Save');
$assert_session
->pageTextContains("IEF test nested 1 {$top_level_title} has been created.");
$top_level_node = $this
->drupalGetNodeByTitle($top_level_title);
$this
->assertNotEmpty($top_level_node);
$nested_node = $this
->drupalGetNodeByTitle($nested_title);
$this
->assertNotEmpty($nested_node);
$double_nested_node = $this
->drupalGetNodeByTitle($double_nested_title);
$this
->assertNotEmpty($double_nested_node);
$this
->checkNestedNodes($top_level_node, $nested_node, $double_nested_node);
}
}
/**
* Tests if editing and removing entities work.
*/
public function testEntityEditingAndRemoving() {
// Get the xpath selectors for the fields in this test.
$inner_title_field_xpath = $this
->getXpathForNthInputByLabelText('Title', 2);
$first_name_field_xpath = $this
->getXpathForNthInputByLabelText('First name', 1);
$last_name_field_xpath = $this
->getXpathForNthInputByLabelText('Last name', 1);
$first_delete_checkbox_xpath = $this
->getXpathForNthInputByLabelText('Delete this node from the system.', 1);
$assert_session = $this
->assertSession();
$page = $this
->getSession()
->getPage();
// Allow addition of existing nodes.
$this
->updateSetting('allow_existing', TRUE);
// Create three ief_reference_type entities.
$referenceNodes = $this
->createReferenceContent();
$this
->drupalCreateNode([
'type' => 'ief_test_complex',
'title' => 'Some title',
'multi' => array_values($referenceNodes),
]);
$parent_node = $this
->drupalGetNodeByTitle('Some title');
// Edit the second entity.
$this
->drupalGet('node/' . $parent_node
->id() . '/edit');
$assert_session
->elementExists('xpath', '(//input[@value="Edit"])[2]')
->press();
$this
->assertNotEmpty($assert_session
->waitForElement('xpath', $inner_title_field_xpath));
$assert_session
->elementExists('xpath', $first_name_field_xpath)
->setValue('John');
$assert_session
->elementExists('xpath', $last_name_field_xpath)
->setValue('Doe');
$page
->pressButton('Update node');
$this
->assertNotEmpty($assert_session
->waitForElementRemoved('css', 'div[data-drupal-selector="edit-multi-form-inline-entity-form-entities-1-form"]'));
$this
->waitForRowByTitle('Some reference 2');
// Save the ief_test_complex node.
$page
->pressButton('Save');
$assert_session
->pageTextContains('IEF test complex Some title has been updated.');
// Checks values of changed entities.
$node = $this
->drupalGetNodeByTitle('Some reference 2', TRUE);
$this
->assertSame('John', $node->first_name->value, 'First name in reference node changed to John');
$this
->assertSame('Doe', $node->last_name->value, 'Last name in reference node changed to Doe');
// Delete the second entity.
$this
->drupalGet('node/' . $parent_node
->id() . '/edit');
$assert_session
->elementsCount('css', 'tr.ief-row-entity', 3);
$assert_session
->elementExists('xpath', '(//input[@value="Remove"])[2]')
->press();
$this
->assertNotEmpty($confirm_checkbox = $assert_session
->waitForElement('xpath', $first_delete_checkbox_xpath));
$assert_session
->pageTextContains('Are you sure you want to remove Some reference 2?');
$confirm_checkbox
->check();
$assert_session
->elementExists('xpath', '(//input[@value="Remove"])[2]')
->press();
$this
->waitForRowRemovedByTitle('Some reference 2');
// Assert two rows show, instead of 3.
$assert_session
->elementsCount('css', 'tr.ief-row-entity', 2);
// Save the ief_test_complex node.
$page
->pressButton('Save');
$assert_session
->pageTextContains('IEF test complex Some title has been updated.');
$deleted_node = $this
->drupalGetNodeByTitle('Some reference 2');
$this
->assertEmpty($deleted_node, 'The inline entity was deleted from the site.');
// Checks that entity does nor appear in IEF.
$this
->drupalGet('node/' . $parent_node
->id() . '/edit');
// Assert 2 rows show, instead of 3.
$assert_session
->elementsCount('css', 'tr.ief-row-entity', 2);
$this
->assertRowByTitle('Some reference 1');
$this
->assertNoRowByTitle('Some reference 2');
$this
->assertRowByTitle('Some reference 3');
// Delete the third entity reference only, don't delete the node. The third
// entity now is second referenced entity because the second one was deleted
// in previous step.
$this
->drupalGet('node/' . $parent_node
->id() . '/edit');
$assert_session
->elementsCount('css', 'tr.ief-row-entity', 2);
$assert_session
->elementExists('xpath', '(//input[@value="Remove"])[2]')
->press();
$this
->assertNotEmpty($assert_session
->waitForElement('xpath', $first_delete_checkbox_xpath));
$assert_session
->pageTextContains('Are you sure you want to remove Some reference 3?');
$assert_session
->elementExists('xpath', '(//input[@value="Remove"])[2]')
->press();
$this
->waitForRowRemovedByTitle('Some reference 3');
// Assert only one row displays.
$assert_session
->elementsCount('css', 'tr.ief-row-entity', 1);
$this
->assertRowByTitle('Some reference 1');
$this
->assertNoRowByTitle('Some reference 2');
$this
->assertNoRowByTitle('Some reference 3');
// Save the ief_test_complex node.
$page
->pressButton('Save');
$assert_session
->pageTextContains('IEF test complex Some title has been updated.');
// Checks that entity is not deleted.
$node = $this
->drupalGetNodeByTitle('Some reference 3');
$this
->assertNotEmpty($node, 'Reference node not deleted');
}
/**
* Tests if referencing existing entities work.
*/
public function testReferencingExistingEntities() {
// Get the xpath selectors for the input fields in this test.
$node_field_xpath = $this
->getXpathForNthInputByLabelText('Node', 1);
$assert_session = $this
->assertSession();
$page = $this
->getSession()
->getPage();
// Allow addition of existing nodes.
$this
->updateSetting('allow_existing', TRUE);
// Create three ief_reference_type entities.
$referenceNodes = $this
->createReferenceContent();
// Create a node for every bundle available.
$bundle_nodes = $this
->createNodeForEveryBundle();
// Create ief_test_complex node with first ief_reference_type node and first
// node from bundle nodes.
$this
->drupalCreateNode([
'type' => 'ief_test_complex',
'title' => 'Some title',
'multi' => [
1,
],
'all_bundles' => key($bundle_nodes),
]);
// Remove first node since we already added it.
unset($bundle_nodes[key($bundle_nodes)]);
$parent_node = $this
->drupalGetNodeByTitle('Some title', TRUE);
// Add remaining existing reference nodes.
$this
->drupalGet('node/' . $parent_node
->id() . '/edit');
for ($i = 2; $i <= 3; $i++) {
$this
->openMultiExistingForm();
$title = 'Some reference ' . $i;
$assert_session
->elementExists('xpath', $node_field_xpath)
->setValue($title . ' (' . $referenceNodes[$title] . ')');
$page
->pressButton('Add node');
$this
->waitForRowByTitle($title);
}
// Add all remaining nodes from all bundles.
foreach ($bundle_nodes as $id => $title) {
$all_bundles_fieldset = $assert_session
->elementExists('css', 'fieldset[data-drupal-selector="edit-all-bundles"]');
$assert_session
->buttonExists('Add existing node', $all_bundles_fieldset)
->press();
$this
->assertNotEmpty($assert_session
->waitForElement('xpath', $node_field_xpath));
$assert_session
->elementExists('xpath', $node_field_xpath)
->setValue($title . ' (' . $id . ')');
$page
->pressButton('Add node');
$this
->waitForRowByTitle($title);
}
// Save the node.
$page
->pressButton('Save');
$assert_session
->pageTextContains('IEF test complex Some title has been updated.');
// Check if entities are referenced.
$this
->drupalGet('node/' . $parent_node
->id() . '/edit');
$assert_session
->elementsCount('css', 'fieldset[data-drupal-selector="edit-multi"] tr.ief-row-entity', 3);
$this
->assertRowByTitle('Some reference 1');
$this
->assertRowByTitle('Some reference 2');
$this
->assertRowByTitle('Some reference 3');
// Check if all remaining nodes from all bundles are referenced.
$assert_session
->elementsCount('css', 'fieldset[data-drupal-selector="edit-all-bundles"] tr.ief-row-entity', 12);
foreach ($bundle_nodes as $title) {
$this
->assertRowByTitle($title);
}
}
/**
* Tests if referencing an existing entity works without submitting the form.
*/
public function testReferencingExistingEntitiesNoSubmit() {
// Get the xpath selectors for the input fields in this test.
$node_field_xpath = $this
->getXpathForNthInputByLabelText('Node', 1);
$title_field_xpath = $this
->getXpathForNthInputByLabelText('Title', 1);
// Allow addition of existing nodes.
$this
->updateSetting('allow_existing', TRUE);
$title = $this
->randomMachineName();
$this
->drupalCreateNode([
'type' => 'ief_reference_type',
'title' => $title,
'first_name' => $this
->randomMachineName(),
'last_name' => $this
->randomMachineName(),
]);
$node = $this
->drupalGetNodeByTitle($title);
$this
->assertNotEmpty($node, 'Created ief_reference_type node "' . $node
->label() . '"');
$this
->drupalGet($this->formContentAddUrl);
$assert_session = $this
->assertSession();
$page = $this
->getSession()
->getPage();
$this
->openMultiExistingForm();
$assert_session
->elementExists('xpath', $node_field_xpath)
->setValue($node
->getTitle() . ' (' . $node
->id() . ')');
$parent_title = $this
->randomMachineName();
$assert_session
->elementExists('xpath', $title_field_xpath)
->setValue($parent_title);
$page
->pressButton('Save');
$assert_session
->pageTextContains("IEF test complex {$parent_title} has been created.");
$assert_session
->pageTextNotContains('This value should not be null.');
$node = $this
->drupalGetNodeByTitle($parent_title);
$this
->assertNotEmpty($node, 'Created ief_reference_type node.');
}
/**
* Test if invalid values get correct validation messages.
*
* Tests validation in reference existing entity form. It also checks if
* existing entity reference form can be canceled.
*/
public function testReferenceExistingValidation() {
// Get the xpath selectors for the input fields in this test.
$node_field_xpath = $this
->getXpathForNthInputByLabelText('Node', 1);
$page = $this
->getSession()
->getPage();
$assert_session = $this
->assertSession();
$this
->updateSetting('allow_existing', TRUE);
$this
->drupalGet('node/add/ief_test_complex');
$this
->checkExistingValidationExpectation('', 'Node field is required.');
$this
->checkExistingValidationExpectation('Fake Title', 'There are no entities matching "Fake Title"');
// Check adding nodes that cannot be referenced by this field.
foreach ($this
->createNodeForEveryBundle() as $id => $title) {
$node = Node::load($id);
if ($node
->bundle() !== 'ief_reference_type') {
$this
->checkExistingValidationExpectation("{$title} ({$id})", "The referenced entity (node: {$id}) does not exist.");
}
}
foreach ($this
->createReferenceContent(2) as $title => $id) {
$this
->openMultiExistingForm();
$current_title = "{$title} ({$id})";
$assert_session
->elementExists('xpath', $node_field_xpath)
->setValue($current_title);
$page
->pressButton('Add node');
$this
->waitForRowByTitle($title);
$assert_session
->elementNotExists('xpath', $node_field_xpath);
// Try to add the same node again.
$this
->checkExistingValidationExpectation($current_title, 'The selected node has already been added.');
}
}
/**
* Tests if duplicating entities works.
*/
public function testDuplicatingEntities() {
// Get the xpath selectors for the input fields in this test.
$title_field_xpath = $this
->getXpathForNthInputByLabelText('Title', 2);
$first_name_field_xpath = $this
->getXpathForNthInputByLabelText('First name', 1);
$page = $this
->getSession()
->getPage();
$assert_session = $this
->assertSession();
$this
->updateSetting('allow_duplicate', TRUE);
$referenceNodes = $this
->createReferenceContent(2);
$this
->drupalCreateNode([
'type' => 'ief_test_complex',
'title' => 'Some title',
'multi' => array_values($referenceNodes),
]);
$parent_node = $this
->drupalGetNodeByTitle('Some title');
$this
->drupalGet('node/' . $parent_node
->id() . '/edit');
$this
->assertNotEmpty($multi_fieldset = $assert_session
->waitForElement('css', 'fieldset[data-drupal-selector="edit-multi"]'));
$assert_session
->buttonExists('Duplicate', $multi_fieldset)
->press();
$this
->assertNotEmpty($create_node_button = $assert_session
->waitForButton('Duplicate node'));
$assert_session
->elementExists('xpath', $title_field_xpath)
->setValue('Duplicate!');
$assert_session
->elementExists('xpath', $first_name_field_xpath)
->setValue('Bojan');
$create_node_button
->press();
$this
->waitForRowByTitle('Duplicate!');
$assert_session
->elementsCount('css', 'tr.ief-row-entity', 3);
$this
->assertRowByTitle('Some reference 1');
$this
->assertRowByTitle('Some reference 2');
$this
->assertRowByTitle('Duplicate!');
$page
->pressButton('Save');
$duplicate = $this
->drupalGetNodeByTitle('Duplicate!');
$this
->assertNotEmpty($duplicate, 'Duplicate node created.');
$this
->assertSame('Bojan', $duplicate->first_name->value);
}
/**
* Tests if a referenced content can be edited.
*
* When the referenced content is newer than the referencing parent node,
* test if a referenced content can be edited.
*/
public function testEditedInlineEntityValidation() {
// Get the xpath selectors for the input fields in this test.
$nested_title_field_xpath = $this
->getXpathForNthInputByLabelText('Title', 2);
$title_field_xpath = $this
->getXpathForNthInputByLabelText('Title', 1);
$page = $this
->getSession()
->getPage();
$assert_session = $this
->assertSession();
$this
->updateSetting('allow_existing', TRUE);
// Create referenced content.
$referenced_nodes = $this
->createReferenceContent(1);
// Create first referencing node.
$this
->drupalCreateNode([
'type' => 'ief_test_complex',
'title' => 'First referencing node',
'multi' => array_values($referenced_nodes),
]);
$first_node = $this
->drupalGetNodeByTitle('First referencing node');
// Create second referencing node.
$this
->drupalCreateNode([
'type' => 'ief_test_complex',
'title' => 'Second referencing node',
'multi' => array_values($referenced_nodes),
]);
$second_node = $this
->drupalGetNodeByTitle('Second referencing node');
// Edit referenced content in first node.
$this
->drupalGet('node/' . $first_node
->id() . '/edit');
$page
->pressButton('Edit');
$this
->assertNotEmpty($nested_title = $assert_session
->waitForElement('xpath', $nested_title_field_xpath));
$nested_title
->setValue('Some reference updated');
$page
->pressButton('Update node');
$this
->waitForRowByTitle('Some reference updated');
$assert_session
->elementsCount('css', 'tr.ief-row-entity', 1);
// Save the first node after editing the reference.
$assert_session
->elementExists('xpath', $title_field_xpath)
->setValue('First node updated');
$page
->pressButton('Save');
$assert_session
->pageTextContains('IEF test complex First node updated has been updated.');
// The changed value of the referenced content is now newer than the
// changed value of the second node.
// Edit referenced content in second node.
$this
->drupalGet('node/' . $second_node
->id() . '/edit');
// Edit referenced node.
$page
->pressButton('Edit');
$this
->assertNotEmpty($nested_title = $assert_session
->waitForElement('xpath', $nested_title_field_xpath));
$nested_title
->setValue('Some reference updated the second time');
$page
->pressButton('Update node');
$this
->waitForRowByTitle('Some reference updated the second time');
$assert_session
->elementsCount('css', 'tr.ief-row-entity', 1);
// Save the second node after editing the reference.
$assert_session
->elementExists('xpath', $title_field_xpath)
->setValue('Second node updated');
$page
->pressButton('Save');
$assert_session
->pageTextContains('IEF test complex Second node updated has been updated.');
// Check if the referenced content could be edited.
$assert_session
->pageTextNotContains('The content has either been modified by another user, or you have already submitted modifications. As a result, your changes cannot be saved.');
}
/**
* Checks that nested IEF entity references can be edited and saved.
*
* @param \Drupal\node\NodeInterface $node
* Top level node of type ief_test_nested1 to check.
*/
protected function checkNestedNodeEditing(NodeInterface $node) {
// Get the xpath selectors for the input fields in this test.
$double_nested_title_field_xpath = $this
->getXpathForNthInputByLabelText('Title', 3);
$title_field_xpath = $this
->getXpathForNthInputByLabelText('Title', 1);
$assert_session = $this
->assertSession();
$page = $this
->getSession()
->getPage();
$nested_node = $node->test_ref_nested1->entity;
$double_nested_node = $nested_node->test_ref_nested2->entity;
$this
->drupalGet("node/{$node->id()}/edit");
$this
->assertRowByTitle($nested_node
->label());
$page
->pressButton('Edit');
$this
->waitForRowByTitle($double_nested_node
->label());
$page
->pressButton('Edit');
$this
->assertNotEmpty($assert_session
->waitforButton('Update node 3'));
$double_nested_node_update_title = $double_nested_node
->getTitle() . ' - updated';
$assert_session
->elementExists('xpath', $double_nested_title_field_xpath)
->setValue($double_nested_node_update_title);
// Close the double nested IEF form.
$page
->pressButton('Update node 3');
$this
->waitForRowByTitle($double_nested_node_update_title);
// Close the nested IEF form.
$page
->pressButton('Update node 2');
$this
->assertNotEmpty($assert_session
->waitForElementRemoved('css', 'div[data-drupal-selector="edit-test-ref-nested1-form-inline-entity-form-entities-0-form"]'));
$this
->waitForRowByTitle($nested_node
->label());
// Save the top level node.
$page
->pressButton('Save');
$assert_session
->pageTextContains('IEF test nested 1 ' . $node
->label() . ' has been updated.');
// Verify the double nested node title change saved properly.
$this
->drupalGet("node/{$node->id()}/edit");
$page
->pressButton('Edit');
$this
->waitForRowByTitle($double_nested_node_update_title);
$this
->drupalGet("node/{$double_nested_node->id()}/edit");
$this
->assertSame($double_nested_node_update_title, $assert_session
->elementExists('xpath', $title_field_xpath)
->getValue());
}
/**
* Creates ief_reference_type nodes which shall serve as reference nodes.
*
* @param int $numNodes
* The number of nodes to create.
*
* @return array
* Array of created node ids keyed by labels.
*/
protected function createReferenceContent($numNodes = 3) {
$retval = [];
for ($i = 1; $i <= $numNodes; $i++) {
$this
->drupalCreateNode([
'type' => 'ief_reference_type',
'title' => 'Some reference ' . $i,
'first_name' => 'First Name ' . $i,
'last_name' => 'Last Name ' . $i,
]);
$node = $this
->drupalGetNodeByTitle('Some reference ' . $i);
$this
->assertNotEmpty($node, 'Created ief_reference_type node "' . $node
->label() . '"');
$retval[$node
->label()] = $node
->id();
}
return $retval;
}
/**
* Updates an IEF setting and saves the underlying entity display.
*
* @param string $name
* The name of the setting.
* @param mixed $value
* The value to set.
*/
protected function updateSetting(string $name, $value) {
/** @var \Drupal\Core\Entity\Display\EntityFormDisplayInterface $display */
$display = $this->entityFormDisplayStorage
->load('node.ief_test_complex.default');
$component = $display
->getComponent('multi');
$component['settings'][$name] = $value;
$display
->setComponent('multi', $component)
->save();
}
/**
* Creates a node for every node bundle.
*
* @return array
* Array of node titles keyed by ids.
*/
protected function createNodeForEveryBundle() {
$retval = [];
$bundles = $this->container
->get('entity_type.bundle.info')
->getBundleInfo('node');
foreach ($bundles as $id => $value) {
$this
->drupalCreateNode([
'type' => $id,
'title' => $value['label'],
]);
$node = $this
->drupalGetNodeByTitle($value['label']);
$this
->assertNotEmpty($node, 'Created node "' . $node
->label() . '"');
$retval[$node
->id()] = $value['label'];
}
return $retval;
}
/**
* Set up the ief_test_nested1 node add form.
*
* Sets the nested fields' required settings.
* Gets the form.
* Opens the inline entity forms if they are not required.
*
* @param bool $required
* Whether the fields are required.
*/
protected function setupNestedComplexForm(bool $required) {
$assert_session = $this
->assertSession();
$page = $this
->getSession()
->getPage();
/** @var \Drupal\Core\Field\FieldConfigInterface $ief_test_nested1 */
$this->fieldConfigStorage
->load('node.ief_test_nested1.test_ref_nested1')
->setRequired($required)
->save();
/** @var \Drupal\Core\Field\FieldConfigInterface $ief_test_nested2 */
$this->fieldConfigStorage
->load('node.ief_test_nested2.test_ref_nested2')
->setRequired($required)
->save();
$this
->drupalGet('node/add/ief_test_nested1');
if (!$required) {
// Open inline forms if not required.
$page
->pressButton('Add new node 2');
$this
->assertNotEmpty($button = $assert_session
->waitForButton('Add new node 3'));
$button
->press();
$this
->assertNotEmpty($assert_session
->waitForButton('Create node 3'));
}
}
/**
* Opens the existing node form on the "multi" field.
*/
protected function openMultiExistingForm() {
$assert_session = $this
->assertSession();
$this
->assertNotEmpty($multi_fieldset = $assert_session
->waitForElement('css', 'fieldset[data-drupal-selector="edit-multi"]'));
$assert_session
->buttonExists('Add existing node', $multi_fieldset)
->press();
$this
->assertNotEmpty($assert_session
->waitForElement('xpath', $this
->getXpathForAutoCompleteInput()));
}
/**
* Check existing node field validation.
*
* Checks that an invalid value for an existing node will be display the
* expected error.
*
* @param string $existing_node_text
* The text to enter into the existing node text field.
* @param string $expected_error
* The error message that is expected to be shown.
*/
protected function checkExistingValidationExpectation(string $existing_node_text, string $expected_error) {
$page = $this
->getSession()
->getPage();
$assert_session = $this
->assertSession();
$this
->openMultiExistingForm();
$field = $assert_session
->waitForElement('xpath', $this
->getXpathForAutoCompleteInput());
$field
->setValue($existing_node_text);
$page
->pressButton('Add node');
$this
->assertNotNull($assert_session
->waitForText($expected_error));
$assert_session
->buttonExists('Cancel')
->press();
$this
->assertNotEmpty($assert_session
->waitForElementRemoved('xpath', $this
->getXpathForAutoCompleteInput()));
}
/**
* Tests create access on IEF Complex content type.
*/
public function testComplexEntityCreate() {
// Get the xpath selectors for the input fields in this test.
$nested_title_field_xpath = $this
->getXpathForNthInputByLabelText('Title', 2);
$user = $this
->createUser([
'create ief_test_complex content',
]);
$this
->drupalLogin($user);
$this
->drupalGet('node/add/ief_test_complex');
$assert_session = $this
->assertSession();
$assert_session
->fieldNotExists('all_bundles[actions][bundle]');
$assert_session
->elementNotExists('xpath', $nested_title_field_xpath);
$user = $this
->createUser([
'create ief_test_complex content',
'create ief_reference_type content',
]);
$this
->drupalLogin($user);
$this
->drupalGet('node/add/ief_test_complex');
$assert_session
->fieldExists('all_bundles[actions][bundle]');
$this
->assertSession()
->optionExists('edit-all-bundles-actions-bundle', 'ief_reference_type');
$this
->assertSession()
->optionExists('edit-all-bundles-actions-bundle', 'ief_test_complex');
$assert_session
->elementExists('xpath', $nested_title_field_xpath);
}
/**
* Checks if nested nodes for ief_test_nested1 content are created.
*
* @param \Drupal\node\NodeInterface $top_level_node
* The top level node.
* @param \Drupal\node\NodeInterface $nested_node
* The second level node.
* @param \Drupal\node\NodeInterface $double_nested_node
* The the third level node.
*/
protected function checkNestedNodes(NodeInterface $top_level_node, NodeInterface $nested_node, NodeInterface $double_nested_node) {
// Check the type and title of the second level node.
if ($nested_node
->id() == $top_level_node->test_ref_nested1->entity
->id()) {
$this
->assertEquals(1, $top_level_node->test_ref_nested1
->count(), 'Only one nested node created');
$this
->assertSame($top_level_node->test_ref_nested1->entity
->label(), $nested_node
->label(), "Nested node's title is correct.");
$this
->assertSame('ief_test_nested2', $nested_node
->bundle(), "Nested node's type is correct.");
// Check the type and title of the third level node.
if ($double_nested_node
->id() == $nested_node->test_ref_nested2->entity
->id()) {
$this
->assertEquals(1, $nested_node->test_ref_nested2
->count(), 'Only one node within a node within a node created.');
$this
->assertSame($nested_node->test_ref_nested2->entity
->label(), $double_nested_node
->label(), "Node within a node within a node's title is correct.");
$this
->assertSame('ief_test_nested3', $double_nested_node
->bundle(), "Node within a node within a node's type is correct.");
$this
->checkNestedNodeEditing($top_level_node);
}
}
}
/**
* Tests the separation of nested data.
*
* Using entity creation with different bundles nested in each other.
* Ief_test_nested1 -> ief_test_nested2 -> ief_test_nested3
*
* When creating a second ief_test_nested2 it should be empty and not be
* prefilled with the ief_test_nested3 of the first ief_test_nested2.
*/
public function testSeparateNestedDataMultiValueFields() {
// Get the xpath selectors for the input fields in this test.
$top_title_field_xpath = $this
->getXpathForNthInputByLabelText('Title', 1);
$nested_title_field_xpath = $this
->getXpathForNthInputByLabelText('Title', 2);
$double_nested_title_field_xpath = $this
->getXpathForNthInputByLabelText('Title', 3);
$page = $this
->getSession()
->getPage();
$assert_session = $this
->assertSession();
foreach ([
FALSE,
TRUE,
] as $required) {
$this
->setupNestedComplexForm($required);
$required_string = $required ? ' required' : ' unrequired';
$double_nested_title = 'Dream within a dream' . $required_string;
$nested_title = 'Dream' . $required_string;
$top_level_title = 'Reality' . $required_string;
$assert_session
->elementExists('xpath', $top_title_field_xpath)
->setValue($top_level_title);
$assert_session
->elementExists('xpath', $nested_title_field_xpath)
->setValue($nested_title);
$assert_session
->elementExists('xpath', $double_nested_title_field_xpath)
->setValue($double_nested_title);
$page
->pressButton('Create node 3');
$assert_session
->waitForButton('Add new node 3');
$page
->pressButton('Create node 2');
$assert_session
->waitForButton('Add new node 2');
$page
->pressButton('Add new node 2');
$assert_session
->waitForButton('Add new node 3');
// The new node 2 should be empty and not already have a
// double_nested_title present.
$this
->assertNoRowByTitle($double_nested_title);
}
}
/**
* Tests that create and edit of nested data won#t clash.
*
* When creating, then editing a nested IEF, the internal widget state must
* use the same IEF ID on create and edit. Otherwise on saving, the entity
* will be saved twice, and cause a WSOD.
*
* @dataProvider simpleFalseTrueDataProvider
*/
public function testNestedCreateAndEditWontClash(bool $required) {
// Get the xpath selectors for the input fields in this test.
$top_title_field_xpath = $this
->getXpathForNthInputByLabelText('Title', 1);
$nested_title_field_xpath = $this
->getXpathForNthInputByLabelText('Title', 2);
$double_nested_title_field_xpath = $this
->getXpathForNthInputByLabelText('Title', 3);
$second_edit_button_xpath = $this
->getXpathForButtonWithValue('Edit', 2);
$assert_session = $this
->assertSession();
$this
->setupNestedComplexForm($required);
$required_string = $required ? ' required' : ' unrequired';
$title_1 = 'Rationality' . $required_string;
$title_1_2 = 'Drain' . $required_string;
$title_1_2_3 = 'Drain within a drain' . $required_string;
$title_i_2_3a = "Drone within a drain" . $required_string;
$title_1_2a = 'Drone' . $required_string;
$title_1_2a_3 = 'Drain within a drone' . $required_string;
$title_i_2a_3a = "Drone within a drain" . $required_string;
$this
->elementWithXpath($top_title_field_xpath)
->setValue($title_1);
$this
->elementWithXpath($nested_title_field_xpath)
->setValue($title_1_2);
$this
->elementWithXpath($double_nested_title_field_xpath)
->setValue($title_1_2_3);
// Close all subforms.
$this
->elementWithXpath($this
->buttonXpath('Create node 3'))
->press();
$this
->waitForXpath($this
->buttonXpath('Add new node 3'));
$this
->elementWithXpath($this
->buttonXpath('Create node 2'))
->press();
$this
->waitForXpath($this
->buttonXpath('Add new node 2'));
// Re-open all subforms and add a second node 3.
$this
->elementWithXpath($this
->buttonXpath('Edit'))
->press();
$this
->waitForXpath($this
->buttonXpath('Update node 2'));
$this
->elementWithXpath($this
->buttonXpath('Add new node 3'))
->press();
$this
->assertNotNull($assert_session
->waitForButton('Create node 3'));
$assert_session
->elementExists('xpath', $double_nested_title_field_xpath)
->setValue($title_i_2_3a);
$this
->elementWithXpath($this
->buttonXpath('Create node 3'))
->press();
$this
->waitForXpath($this
->buttonXpath('Add new node 3'));
$this
->elementWithXpath($this
->buttonXpath('Update node 2'))
->press();
$this
->waitForXpathRemoved($this
->buttonXpath('Update node 2'));
// Repeat. Add node 2a and 2a_3.
$this
->elementWithXpath($this
->buttonXpath('Add new node 2'))
->press();
$this
->waitForXpath($this
->buttonXpath('Create node 2'));
if (!$required) {
$this
->elementWithXpath($this
->buttonXpath('Add new node 3'))
->press();
$this
->waitForXpath($this
->buttonXpath('Create node 3'));
}
$assert_session
->elementExists('xpath', $nested_title_field_xpath)
->setValue($title_1_2a);
$assert_session
->elementExists('xpath', $double_nested_title_field_xpath)
->setValue($title_1_2a_3);
// Close all subforms.
$this
->elementWithXpath($this
->buttonXpath('Create node 3'))
->press();
$this
->waitForXpath($this
->buttonXpath('Add new node 3'));
$this
->elementWithXpath($this
->buttonXpath('Create node 2'))
->press();
$this
->waitForXpathRemoved($this
->buttonXpath('Create node 2'));
// Re-open all subforms and add a second node 2a_3a.
$this
->waitForXpath($second_edit_button_xpath)
->press();
$this
->waitForXpath($this
->buttonXpath('Update node 2'));
$this
->elementWithXpath($this
->buttonXpath('Add new node 3'))
->press();
$this
->waitForXpath($this
->buttonXpath('Create node 3'));
$assert_session
->elementExists('xpath', $double_nested_title_field_xpath)
->setValue($title_i_2a_3a);
$this
->elementWithXpath($this
->buttonXpath('Create node 3'))
->press();
$this
->waitForXpath($this
->buttonXpath('Add new node 3'));
// Save everything and assert message.
$this
->elementWithXpath($this
->buttonXpath('Save'))
->press();
$this
->htmlOutput();
$assert_session
->pageTextContains("IEF test nested 1 {$title_1} has been created.");
}
/**
* Data provider: FALSE, TRUE.
*/
public function simpleFalseTrueDataProvider() {
return [
[
FALSE,
],
[
TRUE,
],
];
}
/**
* Assert and return an element via XPath. On fail, save output and throw.
*
* @param string $xpath
* The XPath.
*
* @return \Behat\Mink\Element\NodeElement
* The element.
*/
public function elementWithXpath(string $xpath) : NodeElement {
return $this
->waitForXpath($xpath, 0);
}
/**
* Wait, assert, and return an element via XPath.
*
* On fail, save output and throw.
*
* @param string $xpath
* The XPath.
* @param int $timeout
* The timeout in milliseconds.
*
* @return \Behat\Mink\Element\NodeElement
* The element.
*/
public function waitForXpath(string $xpath, int $timeout = 10000) : NodeElement {
$element = $this
->assertSession()
->waitForElement('xpath', $xpath, $timeout);
if (!$element) {
$this
->htmlOutput();
$this
->assertNotNull($element);
}
return $element;
}
/**
* Wait and assert removal of an element via XPath.
*
* On fail, save output and throw.
*
* @param string $xpath
* The XPath.
* @param int $timeout
* The timeout in milliseconds.
*
* @return bool
* Returns always true (else throws).
*/
public function waitForXpathRemoved(string $xpath, int $timeout = 10000) : bool {
$removed = $this
->assertSession()
->waitForElementRemoved('xpath', $xpath, $timeout);
if (!$removed) {
$this
->htmlOutput();
$this
->assertTrue($removed);
}
return $removed;
}
/**
* Get xpath for a button.
*
* @param string $label
* The button's label.
* @param int $index
* The button's index, defaults to 1.
*
* @return string
* The XPath.
*/
protected function buttonXpath(string $label, int $index = 1) : string {
return $this
->getXpathForButtonWithValue($label, $index);
}
}
Members
Name | Modifiers | Type | Description | Overrides |
---|---|---|---|---|
AssertHelperTrait:: |
protected static | function | Casts MarkupInterface objects into strings. | |
AssertLegacyTrait:: |
protected | function | Deprecated Scheduled for removal in Drupal 10.0.0. Use self::assertTrue() instead. | |
AssertLegacyTrait:: |
protected | function | Asserts whether an expected cache tag was present in the last response. | |
AssertLegacyTrait:: |
protected | function | Asserts that the element with the given CSS selector is not present. | |
AssertLegacyTrait:: |
protected | function | Asserts that the element with the given CSS selector is present. | |
AssertLegacyTrait:: |
protected | function | Deprecated Scheduled for removal in Drupal 10.0.0. Use self::assertEquals() instead. | |
AssertLegacyTrait:: |
protected | function | Passes if the raw text IS found escaped on the loaded page, fail otherwise. | |
AssertLegacyTrait:: |
protected | function | Asserts that a field exists with the given name or ID. | |
AssertLegacyTrait:: |
protected | function | Asserts that a field exists with the given ID and value. | |
AssertLegacyTrait:: |
protected | function | Asserts that a field exists with the given name and value. | |
AssertLegacyTrait:: |
protected | function | Asserts that a field exists in the current page by the given XPath. | |
AssertLegacyTrait:: |
protected | function | Asserts that a checkbox field in the current page is checked. | |
AssertLegacyTrait:: |
protected | function | Asserts that a field exists in the current page with a given Xpath result. | |
AssertLegacyTrait:: |
protected | function | Checks that current response header equals value. | |
AssertLegacyTrait:: |
protected | function | Deprecated Scheduled for removal in Drupal 10.0.0. Use self::assertSame() instead. | |
AssertLegacyTrait:: |
protected | function | Deprecated Scheduled for removal in Drupal 10.0.0. Use self::assertEquals() instead. | |
AssertLegacyTrait:: |
protected | function | Passes if a link with the specified label is found. | |
AssertLegacyTrait:: |
protected | function | Passes if a link containing a given href (part) is found. | |
AssertLegacyTrait:: |
protected | function | Asserts whether an expected cache tag was absent in the last response. | |
AssertLegacyTrait:: |
protected | function | Passes if the raw text is not found escaped on the loaded page. | |
AssertLegacyTrait:: |
protected | function | Asserts that a field does NOT exist with the given name or ID. | |
AssertLegacyTrait:: |
protected | function | Asserts that a field does not exist with the given ID and value. | |
AssertLegacyTrait:: |
protected | function | Asserts that a field does not exist with the given name and value. | |
AssertLegacyTrait:: |
protected | function | Asserts that a field does not exist or its value does not match, by XPath. | |
AssertLegacyTrait:: |
protected | function | Asserts that a checkbox field in the current page is not checked. | |
AssertLegacyTrait:: |
protected | function | Passes if a link with the specified label is not found. | |
AssertLegacyTrait:: |
protected | function | Passes if a link containing a given href (part) is not found. | |
AssertLegacyTrait:: |
protected | function | Asserts that a select option does NOT exist in the current page. | |
AssertLegacyTrait:: |
protected | function | Triggers a pass if the Perl regex pattern is not found in the raw content. | |
AssertLegacyTrait:: |
protected | function | Passes if the raw text IS not found on the loaded page, fail otherwise. | 1 |
AssertLegacyTrait:: |
protected | function | Deprecated Scheduled for removal in Drupal 10.0.0. Use self::assertNotEquals() instead. | |
AssertLegacyTrait:: |
protected | function | Passes if the page (with HTML stripped) does not contains the text. | 1 |
AssertLegacyTrait:: |
protected | function | Deprecated Scheduled for removal in Drupal 10.0.0. Use self::assertNotSame() instead. | |
AssertLegacyTrait:: |
protected | function | Passes if the text is found MORE THAN ONCE on the text version of the page. | |
AssertLegacyTrait:: |
protected | function | Asserts that a select option in the current page exists. | |
AssertLegacyTrait:: |
protected | function | Asserts that a select option with the visible text exists. | |
AssertLegacyTrait:: |
protected | function | Asserts that a select option in the current page is checked. | |
AssertLegacyTrait:: |
protected | function | Triggers a pass if the Perl regex pattern is found in the raw content. | |
AssertLegacyTrait:: |
protected | function | Passes if the raw text IS found on the loaded page, fail otherwise. | 1 |
AssertLegacyTrait:: |
protected | function | Asserts the page responds with the specified response code. | 1 |
AssertLegacyTrait:: |
protected | function | Passes if the page (with HTML stripped) contains the text. | 1 |
AssertLegacyTrait:: |
protected | function | Helper for assertText and assertNoText. | |
AssertLegacyTrait:: |
protected | function | Pass if the page title is the given string. | |
AssertLegacyTrait:: |
protected | function | Passes if the text is found ONLY ONCE on the text version of the page. | |
AssertLegacyTrait:: |
protected | function | Passes if the internal browser's URL matches the given path. | |
AssertLegacyTrait:: |
protected | function | Builds an XPath query. | |
AssertLegacyTrait:: |
protected | function | Helper: Constructs an XPath for the given set of attributes and value. | |
AssertLegacyTrait:: |
protected | function | Get all option elements, including nested options, in a select. | |
AssertLegacyTrait:: |
protected | function | Gets the current raw content. | |
AssertLegacyTrait:: |
protected | function | Deprecated Scheduled for removal in Drupal 10.0.0. Use self::assertTrue() instead. | |
AssertLegacyTrait:: |
protected | function | ||
BlockCreationTrait:: |
protected | function | Creates a block instance based on default settings. Aliased as: drupalPlaceBlock | |
BrowserHtmlDebugTrait:: |
protected | property | The Base URI to use for links to the output files. | |
BrowserHtmlDebugTrait:: |
protected | property | Class name for HTML output logging. | |
BrowserHtmlDebugTrait:: |
protected | property | Counter for HTML output logging. | |
BrowserHtmlDebugTrait:: |
protected | property | Counter storage for HTML output logging. | |
BrowserHtmlDebugTrait:: |
protected | property | Directory name for HTML output logging. | |
BrowserHtmlDebugTrait:: |
protected | property | HTML output output enabled. | |
BrowserHtmlDebugTrait:: |
protected | property | The file name to write the list of URLs to. | |
BrowserHtmlDebugTrait:: |
protected | property | HTML output test ID. | |
BrowserHtmlDebugTrait:: |
protected | function | Formats HTTP headers as string for HTML output logging. | |
BrowserHtmlDebugTrait:: |
protected | function | Logs a HTML output message in a text file. | |
BrowserHtmlDebugTrait:: |
protected | function | Creates the directory to store browser output. | |
BrowserTestBase:: |
protected | property | The base URL. | |
BrowserTestBase:: |
protected | property | The config importer that can be used in a test. | |
BrowserTestBase:: |
protected | property | An array of custom translations suitable for drupal_rewrite_settings(). | |
BrowserTestBase:: |
protected | property | The database prefix of this test run. | |
BrowserTestBase:: |
protected | property | Mink session manager. | |
BrowserTestBase:: |
protected | property | ||
BrowserTestBase:: |
protected | property | The original container. | |
BrowserTestBase:: |
protected | property | The original array of shutdown function callbacks. | |
BrowserTestBase:: |
protected | property | ||
BrowserTestBase:: |
protected | property | The profile to install as a basis for testing. | 39 |
BrowserTestBase:: |
protected | property | The app root. | |
BrowserTestBase:: |
protected | property | Browser tests are run in separate processes to prevent collisions between code that may be loaded by tests. | |
BrowserTestBase:: |
protected | property | Time limit in seconds for the test. | |
BrowserTestBase:: |
protected | property | The translation file directory for the test environment. | |
BrowserTestBase:: |
protected | function | Clean up the Simpletest environment. | |
BrowserTestBase:: |
protected | function | Configuration accessor for tests. Returns non-overridden configuration. | |
BrowserTestBase:: |
protected | function | Translates a CSS expression to its XPath equivalent. | |
BrowserTestBase:: |
protected | function | Gets the value of an HTTP response header. | |
BrowserTestBase:: |
protected | function | Returns all response headers. | |
BrowserTestBase:: |
public static | function | Ensures test files are deletable. | |
BrowserTestBase:: |
protected | function | Gets an instance of the default Mink driver. | |
BrowserTestBase:: |
protected | function | Obtain the HTTP client for the system under test. | |
BrowserTestBase:: |
protected | function | Helper function to get the options of select field. | |
BrowserTestBase:: |
protected | function |
Provides a Guzzle middleware handler to log every response received. Overrides BrowserHtmlDebugTrait:: |
|
BrowserTestBase:: |
public | function | Returns Mink session. | |
BrowserTestBase:: |
protected | function | Get session cookies from current session. | |
BrowserTestBase:: |
protected | function |
Retrieves the current calling line in the class under test. Overrides BrowserHtmlDebugTrait:: |
|
BrowserTestBase:: |
public | function | Installs Drupal into the Simpletest site. | 1 |
BrowserTestBase:: |
protected | function | Registers additional Mink sessions. | |
BrowserTestBase:: |
protected | function | Transforms a nested array into a flat array suitable for drupalPostForm(). | |
BrowserTestBase:: |
protected | function | Performs an xpath search on the contents of the internal browser. | |
BrowserTestBase:: |
public | function | 1 | |
BrowserTestBase:: |
public | function | Prevents serializing any properties. | |
ComplexWidgetTest:: |
protected | property | Entity form display storage. | |
ComplexWidgetTest:: |
protected | property | URL to add new content. | |
ComplexWidgetTest:: |
protected static | property |
Modules to enable. Overrides BrowserTestBase:: |
|
ComplexWidgetTest:: |
protected | function | Get xpath for a button. | |
ComplexWidgetTest:: |
protected | function | Check existing node field validation. | |
ComplexWidgetTest:: |
protected | function | Checks that nested IEF entity references can be edited and saved. | |
ComplexWidgetTest:: |
protected | function | Checks if nested nodes for ief_test_nested1 content are created. | |
ComplexWidgetTest:: |
protected | function | Creates a node for every node bundle. | |
ComplexWidgetTest:: |
protected | function | Creates ief_reference_type nodes which shall serve as reference nodes. | |
ComplexWidgetTest:: |
public | function | Assert and return an element via XPath. On fail, save output and throw. | |
ComplexWidgetTest:: |
protected | function | Opens the existing node form on the "multi" field. | |
ComplexWidgetTest:: |
protected | function |
Overrides InlineEntityFormTestBase:: |
|
ComplexWidgetTest:: |
protected | function | Set up the ief_test_nested1 node add form. | |
ComplexWidgetTest:: |
public | function | Data provider: FALSE, TRUE. | |
ComplexWidgetTest:: |
public | function | Tests create access on IEF Complex content type. | |
ComplexWidgetTest:: |
public | function | Tests if duplicating entities works. | |
ComplexWidgetTest:: |
public | function | Tests if a referenced content can be edited. | |
ComplexWidgetTest:: |
public | function | Tests if form behaves correctly when field is empty. | |
ComplexWidgetTest:: |
public | function | Tests creation of entities. | |
ComplexWidgetTest:: |
public | function | Tests if editing and removing entities work. | |
ComplexWidgetTest:: |
public | function | Tests that create and edit of nested data won#t clash. | |
ComplexWidgetTest:: |
public | function | Tests the entity creation with different bundles nested in each other. | |
ComplexWidgetTest:: |
public | function | Tests the entity creation with different bundles nested in each other. | |
ComplexWidgetTest:: |
public | function | Test if invalid values get correct validation messages. | |
ComplexWidgetTest:: |
public | function | Tests if referencing existing entities work. | |
ComplexWidgetTest:: |
public | function | Tests if referencing an existing entity works without submitting the form. | |
ComplexWidgetTest:: |
public | function | Tests the separation of nested data. | |
ComplexWidgetTest:: |
protected | function | Updates an IEF setting and saves the underlying entity display. | |
ComplexWidgetTest:: |
public | function | Wait, assert, and return an element via XPath. | |
ComplexWidgetTest:: |
public | function | Wait and assert removal of an element via XPath. | |
ConfigTestTrait:: |
protected | function | Returns a ConfigImporter object to import test configuration. | |
ConfigTestTrait:: |
protected | function | Copies configuration objects from source storage to target storage. | |
ContentTypeCreationTrait:: |
protected | function | Creates a custom content type based on default settings. Aliased as: drupalCreateContentType | 1 |
FunctionalTestSetupTrait:: |
protected | property | The flag to set 'apcu_ensure_unique_prefix' setting. | 1 |
FunctionalTestSetupTrait:: |
protected | property | The class loader to use for installation and initialization of setup. | |
FunctionalTestSetupTrait:: |
protected | property | The config directories used in this test. | |
FunctionalTestSetupTrait:: |
protected | property | The "#1" admin user. | |
FunctionalTestSetupTrait:: |
protected | function | Execute the non-interactive installer. | 1 |
FunctionalTestSetupTrait:: |
protected | function | Returns all supported database driver installer objects. | |
FunctionalTestSetupTrait:: |
protected | function | Initialize various configurations post-installation. | 2 |
FunctionalTestSetupTrait:: |
protected | function | Initializes the kernel after installation. | |
FunctionalTestSetupTrait:: |
protected | function | Initialize settings created during install. | |
FunctionalTestSetupTrait:: |
protected | function | Initializes user 1 for the site to be installed. | |
FunctionalTestSetupTrait:: |
protected | function | Installs the default theme defined by `static::$defaultTheme` when needed. | |
FunctionalTestSetupTrait:: |
protected | function | Returns the parameters that will be used when Simpletest installs Drupal. | 9 |
FunctionalTestSetupTrait:: |
protected | function | Prepares the current environment for running the test. | 23 |
FunctionalTestSetupTrait:: |
protected | function | Creates a mock request and sets it on the generator. | |
FunctionalTestSetupTrait:: |
protected | function | Resets and rebuilds the environment after setup. | |
FunctionalTestSetupTrait:: |
protected | function | Rebuilds \Drupal::getContainer(). | |
FunctionalTestSetupTrait:: |
protected | function | Resets all data structures after having enabled new modules. | |
FunctionalTestSetupTrait:: |
protected | function | Changes parameters in the services.yml file. | |
FunctionalTestSetupTrait:: |
protected | function | Sets up the base URL based upon the environment variable. | |
FunctionalTestSetupTrait:: |
protected | function | Rewrites the settings.php file of the test site. | |
InlineEntityFormTestBase:: |
protected | property |
The theme to install as the default for testing. Overrides BrowserTestBase:: |
|
InlineEntityFormTestBase:: |
protected | property | Field config storage. | |
InlineEntityFormTestBase:: |
protected | property | Field config storage. | |
InlineEntityFormTestBase:: |
protected | property | User with permissions to create content. | |
InlineEntityFormTestBase:: |
protected | function | Ensures that an entity with a specific label exists. | |
InlineEntityFormTestBase:: |
protected | function | Passes if a node is found for the title. | |
InlineEntityFormTestBase:: |
protected | function | Passes if no node is found for the title. | |
InlineEntityFormTestBase:: |
protected | function | Asserts that an IEF table row does not exist. | |
InlineEntityFormTestBase:: |
protected | function | Asserts that an IEF table row exists. | |
InlineEntityFormTestBase:: |
protected | function | Checks for check correct fields on form displays. | |
InlineEntityFormTestBase:: |
protected | function | Gets IEF button name. | |
InlineEntityFormTestBase:: |
protected | function | Returns xpath selector to the first input with an auto-complete. | |
InlineEntityFormTestBase:: |
protected | function | Returns xpath selector to the index-th button with button text value. | |
InlineEntityFormTestBase:: |
protected | function | Returns xpath selector for fieldset label. | |
InlineEntityFormTestBase:: |
protected | function | Returns xpath selector to the index-th input with label. | |
InlineEntityFormTestBase:: |
protected | function |
Prepares site settings and services before installation. Overrides FunctionalTestSetupTrait:: |
|
InlineEntityFormTestBase:: |
protected | function | Wait for an IEF table row to appear. | |
InlineEntityFormTestBase:: |
protected | function | Wait for an IEF table row to disappear. | |
NodeCreationTrait:: |
protected | function | Creates a node based on default settings. Aliased as: drupalCreateNode | |
NodeCreationTrait:: |
public | function | Get a node from the database based on its title. Aliased as: drupalGetNodeByTitle | |
PhpunitCompatibilityTrait:: |
public | function | Returns a mock object for the specified class using the available method. | |
PhpunitCompatibilityTrait:: |
public | function | Compatibility layer for PHPUnit 6 to support PHPUnit 4 code. | |
RandomGeneratorTrait:: |
protected | property | The random generator. | |
RandomGeneratorTrait:: |
protected | function | Gets the random generator for the utility methods. | |
RandomGeneratorTrait:: |
protected | function | Generates a unique random string containing letters and numbers. | 1 |
RandomGeneratorTrait:: |
public | function | Generates a random PHP object. | |
RandomGeneratorTrait:: |
public | function | Generates a pseudo-random string of ASCII characters of codes 32 to 126. | |
RandomGeneratorTrait:: |
public | function | Callback for random string validation. | |
RefreshVariablesTrait:: |
protected | function | Refreshes in-memory configuration and state information. | 3 |
SessionTestTrait:: |
protected | property | The name of the session cookie. | |
SessionTestTrait:: |
protected | function | Generates a session cookie name. | |
SessionTestTrait:: |
protected | function | Returns the session name in use on the child site. | |
StorageCopyTrait:: |
protected static | function | Copy the configuration from one storage to another and remove stale items. | |
TestFileCreationTrait:: |
protected | property | Whether the files were copied to the test files directory. | |
TestFileCreationTrait:: |
protected | function | Compares two files based on size and file name. | |
TestFileCreationTrait:: |
public static | function | Generates a test file. | |
TestFileCreationTrait:: |
protected | function | Gets a list of files that can be used in tests. Aliased as: drupalGetTestFiles | |
TestRequirementsTrait:: |
private | function | Checks missing module requirements. | |
TestRequirementsTrait:: |
protected | function | Check module requirements for the Drupal use case. | 1 |
TestRequirementsTrait:: |
protected static | function | Returns the Drupal root directory. | |
TestSetupTrait:: |
protected static | property | An array of config object names that are excluded from schema checking. | |
TestSetupTrait:: |
protected | property | The dependency injection container used in the test. | |
TestSetupTrait:: |
protected | property | The DrupalKernel instance used in the test. | |
TestSetupTrait:: |
protected | property | The site directory of the original parent site. | |
TestSetupTrait:: |
protected | property | The private file directory for the test environment. | |
TestSetupTrait:: |
protected | property | The public file directory for the test environment. | |
TestSetupTrait:: |
protected | property | The site directory of this test run. | |
TestSetupTrait:: |
protected | property | Set to TRUE to strict check all configuration saved. | 2 |
TestSetupTrait:: |
protected | property | The temporary file directory for the test environment. | |
TestSetupTrait:: |
protected | property | The test run ID. | |
TestSetupTrait:: |
protected | function | Changes the database connection to the prefixed one. | |
TestSetupTrait:: |
protected | function | Gets the config schema exclusions for this test. | |
TestSetupTrait:: |
public static | function | Returns the database connection to the site running Simpletest. | |
TestSetupTrait:: |
protected | function | Generates a database prefix for running tests. | 2 |
UiHelperTrait:: |
protected | property | The current user logged in using the Mink controlled browser. | |
UiHelperTrait:: |
protected | property | The number of meta refresh redirects to follow, or NULL if unlimited. | |
UiHelperTrait:: |
protected | property | The number of meta refresh redirects followed during ::drupalGet(). | |
UiHelperTrait:: |
protected | function | Builds an a absolute URL from a system path or a URL object. | |
UiHelperTrait:: |
protected | function | Checks for meta refresh tag and if found call drupalGet() recursively. | |
UiHelperTrait:: |
protected | function | Clicks the element with the given CSS selector. | |
UiHelperTrait:: |
protected | function | Follows a link by complete name. | |
UiHelperTrait:: |
protected | function | Searches elements using a CSS selector in the raw content. | |
UiHelperTrait:: |
protected | function | Retrieves a Drupal path or an absolute path. | 3 |
UiHelperTrait:: |
protected | function | Logs in a user using the Mink controlled browser. | |
UiHelperTrait:: |
protected | function | Logs a user out of the Mink controlled browser and confirms. | |
UiHelperTrait:: |
protected | function | Executes a form submission. | |
UiHelperTrait:: |
protected | function | Returns whether a given user account is logged in. | |
UiHelperTrait:: |
protected | function | Takes a path and returns an absolute path. | |
UiHelperTrait:: |
protected | function | Retrieves the plain-text content from the current page. | |
UiHelperTrait:: |
protected | function | Get the current URL from the browser. | |
UiHelperTrait:: |
protected | function | Prepare for a request to testing site. | 1 |
UiHelperTrait:: |
protected | function | Fills and submits a form. | |
UserCreationTrait:: |
protected | function | Checks whether a given list of permission names is valid. | |
UserCreationTrait:: |
protected | function | Creates an administrative role. | |
UserCreationTrait:: |
protected | function | Creates a role with specified permissions. Aliased as: drupalCreateRole | |
UserCreationTrait:: |
protected | function | Create a user with a given set of permissions. Aliased as: drupalCreateUser | |
UserCreationTrait:: |
protected | function | Grant permissions to a user role. | |
UserCreationTrait:: |
protected | function | Switch the current logged in user. | |
UserCreationTrait:: |
protected | function | Creates a random user account and sets it as current user. | |
WebDriverTestBase:: |
protected | property | Disables CSS animations in tests for more reliable testing. | |
WebDriverTestBase:: |
protected | property |
To use a legacy phantomjs based approach, please use PhantomJSDriver::class. Overrides BrowserTestBase:: |
2 |
WebDriverTestBase:: |
protected | function | Asserts that the element with the given CSS selector is not visible. | |
WebDriverTestBase:: |
protected | function | Asserts that the element with the given CSS selector is visible. | |
WebDriverTestBase:: |
protected | function | Waits for the given time or until the given JS condition becomes TRUE. | |
WebDriverTestBase:: |
public | function |
Returns WebAssert object. Overrides UiHelperTrait:: |
1 |
WebDriverTestBase:: |
protected | function | Creates a screenshot. | |
WebDriverTestBase:: |
protected | function |
Gets the current Drupal javascript settings and parses into an array. Overrides BrowserTestBase:: |
|
WebDriverTestBase:: |
protected | function |
Returns headers in HTML output format. Overrides BrowserHtmlDebugTrait:: |
|
WebDriverTestBase:: |
protected | function |
Get the Mink driver args from an environment variable, if it is set. Can
be overridden in a derived class so it is possible to use a different
value for a subset of tests, e.g. the JavaScript tests. Overrides BrowserTestBase:: |
|
WebDriverTestBase:: |
protected | function |
Visits the front page when initializing Mink. Overrides BrowserTestBase:: |
|
WebDriverTestBase:: |
protected | function |
Initializes Mink sessions. Overrides BrowserTestBase:: |
1 |
WebDriverTestBase:: |
protected | function |
Install modules defined by `static::$modules`. Overrides FunctionalTestSetupTrait:: |
|
WebDriverTestBase:: |
protected | function |
Overrides BrowserTestBase:: |
1 |
XdebugRequestTrait:: |
protected | function | Adds xdebug cookies, from request setup. |