class ParagraphsAddWidgetTest

Test paragraphs user interface.

@group paragraphs

Hierarchy

Expanded class hierarchy of ParagraphsAddWidgetTest

File

paragraphs/tests/src/FunctionalJavascript/ParagraphsAddWidgetTest.php, line 15

Namespace

Drupal\Tests\paragraphs\FunctionalJavascript
View source
class ParagraphsAddWidgetTest extends WebDriverTestBase {
  use LoginAdminTrait;
  use FieldUiTestTrait;
  use ParagraphsTestBaseTrait;
  use ParagraphsCoreVersionUiTestTrait;

  /**
   * Modules to enable.
   *
   * @var array
   */
  protected static $modules = [
    'node',
    'paragraphs_test',
    'paragraphs',
    'field',
    'field_ui',
    'block',
    'link',
  ];

  /**
   * {@inheritdoc}
   */
  protected $defaultTheme = 'stark';

  /**
   * {@inheritdoc}
   */
  protected function setUp() : void {
    parent::setUp();
    $this
      ->placeDefaultBlocks();
  }

  /**
   * Tests the add widget button with modal form.
   */
  public function testAddWidgetButton() {
    $this
      ->addParagraphedContentType('paragraphed_test');
    $this
      ->loginAsAdmin([
      'administer content types',
      'administer node form display',
      'edit any paragraphed_test content',
      'create paragraphed_test content',
    ]);

    // Set the add mode on the content type to modal form widget.
    $this
      ->drupalGet('admin/structure/types/manage/paragraphed_test/form-display');
    $page = $this
      ->getSession()
      ->getPage();
    $page
      ->pressButton('field_paragraphs_settings_edit');
    $this
      ->assertSession()
      ->assertWaitOnAjaxRequest();
    $edit = [
      'fields[field_paragraphs][settings_edit_form][settings][edit_mode]' => 'closed',
      'fields[field_paragraphs][settings_edit_form][settings][add_mode]' => 'modal',
    ];
    $this
      ->submitForm($edit, 'Update');
    $this
      ->assertSession()
      ->assertWaitOnAjaxRequest();
    $this
      ->submitForm([], 'Save');

    // Add a Paragraph type.
    $paragraph_type = 'text_paragraph';
    $this
      ->addParagraphsType($paragraph_type);
    $this
      ->addParagraphsType('text');

    // Add icons to the paragraphs types.
    $icon_one = $this
      ->addParagraphsTypeIcon($paragraph_type);
    $icon_two = $this
      ->addParagraphsTypeIcon('text');

    // Add a text field to the text_paragraph type.
    $this
      ->drupalGet('admin/structure/paragraphs_type/' . $paragraph_type . '/fields/add-field');
    if ($this
      ->coreVersion('10.2')) {
      $page
        ->selectFieldOption('new_storage_type', 'formatted_text');
      $this
        ->assertSession()
        ->waitForElementVisible('css', '#text_long');
      $page
        ->selectFieldOption('group_field_options_wrapper', 'text_long');
    }
    else {
      $page
        ->selectFieldOption('new_storage_type', 'text_long');
    }
    $page
      ->fillField('label', 'Text');
    $this
      ->assertSession()
      ->waitForElementVisible('css', '#edit-name-machine-name-suffix .link');
    $page
      ->pressButton('Edit');
    $page
      ->fillField('field_name', 'text');
    if ($this
      ->coreVersion('10.2')) {
      $page
        ->pressButton('Continue');
      $page
        ->pressButton('Save settings');
    }
    else {
      $page
        ->pressButton('Save and continue');
      $page
        ->pressButton('Save field settings');
      $page
        ->pressButton('Save settings');
    }

    // Create paragraph type Nested test.
    $this
      ->addParagraphsType('nested_test');
    $this
      ->drupalGet('/admin/structure/paragraphs_type/nested_test/fields/add-field');
    $page
      ->selectFieldOption('new_storage_type', 'field_ui:entity_reference_revisions:paragraph');
    $page
      ->fillField('label', 'Paragraphs');
    $this
      ->assertSession()
      ->waitForElementVisible('css', '#edit-name-machine-name-suffix .link');
    $page
      ->pressButton('Edit');
    $page
      ->fillField('field_name', 'paragraphs');
    if ($this
      ->coreVersion('10.2')) {
      $page
        ->pressButton('Continue');
      $page
        ->pressButton('Save settings');
    }
    else {
      $page
        ->pressButton('Save and continue');
      $page
        ->pressButton('Save field settings');
      $page
        ->pressButton('Save settings');
    }

    // Set the settings for the field in the nested paragraph.
    $component = [
      'type' => 'paragraphs',
      'region' => 'content',
      'settings' => [
        'edit_mode' => 'closed',
        'add_mode' => 'modal',
        'form_display_mode' => 'default',
      ],
    ];
    EntityFormDisplay::load('paragraph.nested_test.default')
      ->setComponent('field_paragraphs', $component)
      ->save();

    // Add a paragraphed test.
    $this
      ->drupalGet('node/add/paragraphed_test');

    // Add a nested paragraph with the add widget.
    $page
      ->pressButton('Add Paragraph');
    $this
      ->assertSession()
      ->elementTextContains('css', '.ui-dialog-title', 'Add Paragraph');
    $paragraphs_dialog = $this
      ->assertSession()
      ->waitForElementVisible('css', 'div.ui-dialog');
    $paragraphs_dialog
      ->pressButton('nested_test');
    $this
      ->assertSession()
      ->assertWaitOnAjaxRequest();

    // Verify that the paragraphs type icons are being displayed.
    $button_one = $this
      ->assertSession()
      ->buttonExists($paragraph_type);
    $button_two = $this
      ->assertSession()
      ->buttonExists('text');
    $this
      ->assertStringContainsString($icon_one
      ->getFilename(), $button_one
      ->getAttribute('style'));
    $this
      ->assertStringContainsString($icon_two
      ->getFilename(), $button_two
      ->getAttribute('style'));

    // Find the add button in the nested paragraph with xpath.
    $element = $this
      ->xpath('//div[contains(@class, "form-item")]/div/div/div[contains(@class, "paragraph-type-add-modal")]/input');
    $element[0]
      ->click();
    $this
      ->assertSession()
      ->assertWaitOnAjaxRequest();

    // Add a text inside the nested paragraph.
    $page = $this
      ->getSession()
      ->getPage();
    $dialog = $page
      ->find('xpath', '//div[contains(@class, "ui-dialog")]');
    $dialog
      ->pressButton('text');
    $this
      ->assertSession()
      ->assertWaitOnAjaxRequest();
    $edit = [
      'title[0][value]' => 'Example title',
    ];
    $this
      ->submitForm($edit, 'Save');

    // Check the created paragraphed test.
    $this
      ->assertSession()
      ->pageTextContainsOnce('paragraphed_test Example title has been created.');
    $this
      ->assertSession()
      ->elementTextContains('css', '.paragraph--type--nested-test', 'Paragraphs');
    $this
      ->assertSession()
      ->elementTextContains('css', '.paragraph--type--text', '');

    // Add a paragraphs field with another paragraphs widget title to the
    // paragraphed_test content type.
    $this
      ->addParagraphsField('paragraphed_test', 'field_paragraphs_two', 'node');
    $settings = [
      'title' => 'Renamed paragraph',
      'title_plural' => 'Renamed paragraphs',
      'add_mode' => 'modal',
    ];
    $this
      ->setParagraphsWidgetSettings('paragraphed_test', 'field_paragraphs_two', $settings);

    // Check that the "add" buttons and modal form windows are labeled
    // correctly.
    $this
      ->drupalGet('node/add/paragraphed_test');
    $page
      ->pressButton('Add Paragraph');
    $this
      ->assertSession()
      ->elementTextContains('css', '.ui-dialog-title', 'Add Paragraph');
    $this
      ->assertSession()
      ->elementTextNotContains('css', '.ui-dialog-title', 'Add Renamed paragraph');
    $this
      ->assertSession()
      ->elementExists('css', '.ui-dialog-titlebar-close')
      ->press();
    $page
      ->pressButton('Add Renamed paragraph');
    $this
      ->assertSession()
      ->elementTextContains('css', '.ui-dialog-title', 'Add Renamed paragraph');
    $this
      ->assertSession()
      ->elementTextNotContains('css', '.ui-dialog-title', 'Add Paragraph');
  }

  /**
   * Test Modal add widget with hidden delta field.
   */
  public function testModalAddWidgetDelta() {
    $content_type = 'test_modal_delta';
    $this
      ->addParagraphedContentType($content_type);
    $this
      ->loginAsAdmin([
      "administer content types",
      "administer node form display",
      "edit any {$content_type} content",
      "create {$content_type} content",
    ]);

    // Set the add mode on the content type to modal form widget.
    $this
      ->drupalGet("admin/structure/types/manage/{$content_type}/form-display");
    $page = $this
      ->getSession()
      ->getPage();
    $page
      ->pressButton('field_paragraphs_settings_edit');
    $this
      ->assertSession()
      ->assertWaitOnAjaxRequest();
    $edit = [
      'fields[field_paragraphs][settings_edit_form][settings][edit_mode]' => 'closed',
      'fields[field_paragraphs][settings_edit_form][settings][add_mode]' => 'modal',
    ];
    $this
      ->submitForm($edit, 'Update');
    $this
      ->assertSession()
      ->assertWaitOnAjaxRequest();
    $this
      ->submitForm([], 'Save');

    // Add a Paragraph types.
    $this
      ->addParagraphsType('test_1');
    $this
      ->addParagraphsType('test_2');
    $this
      ->addParagraphsType('test_3');

    // Add a text field to the text_paragraph type.
    $this
      ->drupalGet('admin/structure/paragraphs_type/test_1/fields/add-field');
    if ($this
      ->coreVersion('10.2')) {
      $page
        ->selectFieldOption('new_storage_type', 'formatted_text');
      $this
        ->assertSession()
        ->waitForElementVisible('css', '#text_long');
      $page
        ->selectFieldOption('group_field_options_wrapper', 'text_long');
    }
    else {
      $page
        ->selectFieldOption('new_storage_type', 'text_long');
    }
    $page
      ->fillField('label', 'Text');
    $this
      ->assertSession()
      ->waitForElementVisible('css', '#edit-name-machine-name-suffix .link');
    $page
      ->pressButton('Edit');
    $page
      ->fillField('field_name', 'text_1');
    if ($this
      ->coreVersion('10.2')) {
      $page
        ->pressButton('Continue');
      $page
        ->pressButton('Save settings');
    }
    else {
      $page
        ->pressButton('Save and continue');
      $page
        ->pressButton('Save field settings');
      $page
        ->pressButton('Save settings');
    }
    $this
      ->drupalGet('admin/structure/paragraphs_type/test_2/fields/add-field');
    if ($this
      ->coreVersion('10.2')) {
      $page
        ->selectFieldOption('new_storage_type', 'formatted_text');
      $this
        ->assertSession()
        ->waitForElementVisible('css', '#text_long');
      $page
        ->selectFieldOption('group_field_options_wrapper', 'text_long');
    }
    else {
      $page
        ->selectFieldOption('new_storage_type', 'text_long');
    }
    $page
      ->fillField('label', 'Text');
    $this
      ->assertSession()
      ->waitForElementVisible('css', '#edit-name-machine-name-suffix .link');
    $page
      ->pressButton('Edit');
    $page
      ->fillField('field_name', 'text_2');
    if ($this
      ->coreVersion('10.2')) {
      $page
        ->pressButton('Continue');
      $page
        ->pressButton('Save settings');
    }
    else {
      $page
        ->pressButton('Save and continue');
      $page
        ->pressButton('Save field settings');
      $page
        ->pressButton('Save settings');
    }
    $this
      ->drupalGet('admin/structure/paragraphs_type/test_3/fields/add-field');
    if ($this
      ->coreVersion('10.2')) {
      $page
        ->selectFieldOption('new_storage_type', 'formatted_text');
      $this
        ->assertSession()
        ->waitForElementVisible('css', '#text_long');
      $page
        ->selectFieldOption('group_field_options_wrapper', 'text_long');
    }
    else {
      $page
        ->selectFieldOption('new_storage_type', 'text_long');
    }
    $page
      ->fillField('label', 'Text');
    $this
      ->assertSession()
      ->waitForElementVisible('css', '#edit-name-machine-name-suffix .link');
    $page
      ->pressButton('Edit');
    $page
      ->fillField('field_name', 'test_3');
    if ($this
      ->coreVersion('10.2')) {
      $page
        ->pressButton('Continue');
      $page
        ->pressButton('Save settings');
    }
    else {
      $page
        ->pressButton('Save and continue');
      $page
        ->pressButton('Save field settings');
      $page
        ->pressButton('Save settings');
    }

    // Create paragraph type Nested test.
    $this
      ->addParagraphsType('test_nested');
    $this
      ->drupalGet('/admin/structure/paragraphs_type/test_nested/fields/add-field');
    $page
      ->selectFieldOption('new_storage_type', 'field_ui:entity_reference_revisions:paragraph');
    $page
      ->fillField('label', 'Paragraphs');
    $this
      ->assertSession()
      ->waitForElementVisible('css', '#edit-name-machine-name-suffix .link');
    $page
      ->pressButton('Edit');
    $page
      ->fillField('field_name', 'paragraphs');
    if ($this
      ->coreVersion('10.2')) {
      $page
        ->pressButton('Continue');
      $page
        ->pressButton('Save settings');
    }
    else {
      $page
        ->pressButton('Save and continue');
      $page
        ->pressButton('Save field settings');
      $page
        ->pressButton('Save settings');
    }

    // Set the settings for the field in the nested paragraph.
    $component = [
      'type' => 'paragraphs',
      'region' => 'content',
      'settings' => [
        'edit_mode' => 'closed',
        'add_mode' => 'modal',
        'form_display_mode' => 'default',
      ],
    ];
    EntityFormDisplay::load('paragraph.test_nested.default')
      ->setComponent('field_paragraphs', $component)
      ->save();

    // Add a paragraphed test.
    $this
      ->drupalGet('node/add/test_modal_delta');
    $page
      ->fillField('title[0][value]', 'Test modal add widget delta');

    // Add a nested paragraph with the add widget - use negative delta.
    //
    // This case covers full execution of
    // ParagraphsWidget::prepareDeltaPosition() when list is empty.
    $this
      ->getSession()
      ->executeScript("jQuery('input.paragraph-type-add-delta').last().val(-100)");
    $page
      ->find('xpath', '//*[@name="button_add_modal"]')
      ->click();
    $page
      ->find('xpath', '//*[contains(@class, "paragraphs-add-dialog") and contains(@class, "ui-dialog-content")]//*[contains(@name, "test_nested")]')
      ->click();
    $this
      ->assertSession()
      ->assertWaitOnAjaxRequest();

    // NOTE: After nested paragraphs is added there will be 2 add buttons and we
    // will use xpath "ancestor" axis to switch scope between base paragraphs
    // and nested paragraphs.
    //
    // For jQuery selector, we will use first() and last(), for nested and base
    // paragraph respectively.
    //
    // Add 2 additional paragraphs in base field.
    $this
      ->getSession()
      ->executeScript("jQuery('input.paragraph-type-add-delta').last().val('')");
    for ($i = 1; $i <= 2; $i++) {
      $page
        ->find('xpath', '//*[@name="button_add_modal" and not(ancestor::table)]')
        ->click();
      $this
        ->assertSession()
        ->assertWaitOnAjaxRequest();
      $page
        ->find('xpath', '//*[contains(@class, "paragraphs-add-dialog") and contains(@class, "ui-dialog-content")]//*[contains(@name, "test_' . $i . '")]')
        ->click();
      $this
        ->assertSession()
        ->assertWaitOnAjaxRequest();
    }

    // There should be 3 paragraphs and last one should be "test_2" type.
    $base_paragraphs = $page
      ->findAll('xpath', '//*[contains(@class, "paragraph-type-label") and not(ancestor::div[contains(@class, "paragraphs-nested")])]');
    $this
      ->assertEquals(3, count($base_paragraphs), 'There should be 3 paragraphs.');
    $this
      ->assertEquals('test_2', $base_paragraphs[2]
      ->getText(), 'Last paragraph should be type "test_2".');

    // Add new paragraph to 1st position - set delta to 0 for base paragraphs.
    $this
      ->getSession()
      ->executeScript("jQuery('input.paragraph-type-add-delta').last().val(0)");
    $page
      ->find('xpath', '//*[@name="button_add_modal" and not(ancestor::table)]')
      ->click();
    $this
      ->assertSession()
      ->assertWaitOnAjaxRequest();
    $page
      ->find('xpath', '//*[contains(@class, "paragraphs-add-dialog") and contains(@class, "ui-dialog-content")]//*[contains(@name, "test_3")]')
      ->click();
    $this
      ->assertSession()
      ->assertWaitOnAjaxRequest();

    // There should be 4 paragraphs and first one should be "test_3" type.
    $base_paragraphs = $page
      ->findAll('xpath', '//*[contains(@class, "paragraph-type-label") and not(ancestor::div[contains(@class, "paragraphs-nested")])]');
    $this
      ->assertEquals(4, count($base_paragraphs), 'There should be 4 paragraphs.');
    $this
      ->assertEquals('test_3', $base_paragraphs[0]
      ->getText(), '1st paragraph should be type "test_3".');

    // Add new paragraph to 3rd position - set delta to 2 for base paragraphs.
    $this
      ->getSession()
      ->executeScript("jQuery('input.paragraph-type-add-delta').last().val(2)");
    $page
      ->find('xpath', '//*[@name="button_add_modal" and not(ancestor::table)]')
      ->click();
    $this
      ->assertSession()
      ->assertWaitOnAjaxRequest();
    $page
      ->find('xpath', '//*[contains(@class, "paragraphs-add-dialog") and contains(@class, "ui-dialog-content")]//*[contains(@name, "test_2")]')
      ->click();
    $this
      ->assertSession()
      ->assertWaitOnAjaxRequest();

    // There should be 5 paragraphs and 3rd one should be "test_2" type.
    $base_paragraphs = $page
      ->findAll('xpath', '//*[contains(@class, "paragraph-type-label") and not(ancestor::div[contains(@class, "paragraphs-nested")])]');
    $this
      ->assertEquals(5, count($base_paragraphs), 'There should be 5 paragraphs.');
    $this
      ->assertEquals('test_2', $base_paragraphs[2]
      ->getText(), '3rd paragraph should be type "test_2".');

    // Add new paragraph to last position - using really big delta.
    $this
      ->getSession()
      ->executeScript("jQuery('input.paragraph-type-add-delta').last().val(1000)");
    $page
      ->find('xpath', '//*[@name="button_add_modal" and not(ancestor::table)]')
      ->click();
    $this
      ->assertSession()
      ->assertWaitOnAjaxRequest();
    $page
      ->find('xpath', '//*[contains(@class, "paragraphs-add-dialog") and contains(@class, "ui-dialog-content")]//*[contains(@name, "test_1")]')
      ->click();
    $this
      ->assertSession()
      ->assertWaitOnAjaxRequest();

    // There should be 6 paragraphs and last one should be "test_1" type.
    $base_paragraphs = $page
      ->findAll('xpath', '//*[contains(@class, "paragraph-type-label") and not(ancestor::div[contains(@class, "paragraphs-nested")])]');
    $this
      ->assertEquals(6, count($base_paragraphs), 'There should be 6 paragraphs.');
    $this
      ->assertEquals('test_1', $base_paragraphs[5]
      ->getText(), 'Last paragraph should be type "test_1".');

    // Clear delta base paragraphs.
    $this
      ->getSession()
      ->executeScript("jQuery('input.paragraph-type-add-delta').last().val('')");
    $page
      ->find('xpath', '//*[@name="button_add_modal" and not(ancestor::table)]')
      ->click();
    $this
      ->assertSession()
      ->assertWaitOnAjaxRequest();
    $page
      ->find('xpath', '//*[contains(@class, "paragraphs-add-dialog") and contains(@class, "ui-dialog-content")]//*[contains(@name, "test_3")]')
      ->click();
    $this
      ->assertSession()
      ->assertWaitOnAjaxRequest();

    // There should be 7 paragraphs and last one should be "test_3" type.
    $base_paragraphs = $page
      ->findAll('xpath', '//*[contains(@class, "paragraph-type-label") and not(ancestor::div[contains(@class, "paragraphs-nested")])]');
    $this
      ->assertEquals(7, count($base_paragraphs), 'There should be 7 paragraphs.');
    $this
      ->assertEquals('test_3', $base_paragraphs[6]
      ->getText(), 'Last paragraph should be type "test_3".');

    // Save -> Open -> Check.
    $page
      ->pressButton('Save');
    $this
      ->drupalGet('/node/1/edit');

    // Check order for all Base Paragraphs.
    $base_paragraphs = $page
      ->findAll('xpath', '//*[contains(@class, "paragraph-type-label") and not(ancestor::div[contains(@class, "paragraphs-nested")])]');
    $base_paragraphs_type = [];
    foreach ($base_paragraphs as $base_paragraph) {
      $base_paragraphs_type[] = $base_paragraph
        ->getText();
    }
    $this
      ->assertEquals([
      'test_3',
      'test_nested',
      'test_2',
      'test_1',
      'test_2',
      'test_1',
      'test_3',
    ], $base_paragraphs_type);

    // Test adding in nested paragraphs.
    $page
      ->find('xpath', '//tr[2]/td[2]//*[contains(@class, "paragraphs-icon-button-edit")]')
      ->click();
    $this
      ->assertSession()
      ->assertWaitOnAjaxRequest();

    // Add paragraph in nested to have initial state for adding positions.
    $page
      ->find('xpath', '//*[@name="button_add_modal" and ancestor::table]')
      ->click();
    $this
      ->assertSession()
      ->assertWaitOnAjaxRequest();
    $page
      ->find('xpath', '//*[contains(@class, "paragraphs-add-dialog") and contains(@class, "ui-dialog-content")]//*[contains(@name, "test_1")]')
      ->click();
    $this
      ->assertSession()
      ->assertWaitOnAjaxRequest();

    // Add new paragraph to first position.
    $this
      ->getSession()
      ->executeScript("jQuery('input.paragraph-type-add-delta').first().val(0)");
    $page
      ->find('xpath', '//*[@name="button_add_modal" and ancestor::table]')
      ->click();
    $this
      ->assertSession()
      ->assertWaitOnAjaxRequest();
    $page
      ->find('xpath', '//*[contains(@class, "paragraphs-add-dialog") and contains(@class, "ui-dialog-content")]//*[contains(@name, "test_3")]')
      ->click();
    $this
      ->assertSession()
      ->assertWaitOnAjaxRequest();

    // Add new paragraph to 2nd position - using float value for index.
    $this
      ->getSession()
      ->executeScript("jQuery('input.paragraph-type-add-delta').first().val(1.1111)");
    $page
      ->find('xpath', '//*[@name="button_add_modal" and ancestor::table]')
      ->click();
    $this
      ->assertSession()
      ->assertWaitOnAjaxRequest();
    $page
      ->find('xpath', '//*[contains(@class, "paragraphs-add-dialog") and contains(@class, "ui-dialog-content")]//*[contains(@name, "test_2")]')
      ->click();
    $this
      ->assertSession()
      ->assertWaitOnAjaxRequest();

    // Add new paragraph to first position - using negative index.
    $this
      ->getSession()
      ->executeScript("jQuery('input.paragraph-type-add-delta').first().val(-100)");
    $page
      ->find('xpath', '//*[@name="button_add_modal" and ancestor::table]')
      ->click();
    $this
      ->assertSession()
      ->assertWaitOnAjaxRequest();
    $page
      ->find('xpath', '//*[contains(@class, "paragraphs-add-dialog") and contains(@class, "ui-dialog-content")]//*[contains(@name, "test_2")]')
      ->click();
    $this
      ->assertSession()
      ->assertWaitOnAjaxRequest();

    // Add new paragraph to last position - using some text as position.
    $this
      ->getSession()
      ->executeScript("jQuery('input.paragraph-type-add-delta').first().val('some_text')");
    $page
      ->find('xpath', '//*[@name="button_add_modal" and ancestor::table]')
      ->click();
    $this
      ->assertSession()
      ->assertWaitOnAjaxRequest();
    $page
      ->find('xpath', '//*[contains(@class, "paragraphs-add-dialog") and contains(@class, "ui-dialog-content")]//*[contains(@name, "test_3")]')
      ->click();
    $this
      ->assertSession()
      ->assertWaitOnAjaxRequest();

    // Check order for all Nested Paragraphs.
    $nested_paragraphs = $page
      ->findAll('xpath', '//*[contains(@class, "paragraph-type-label") and ancestor::div[contains(@class, "paragraphs-nested")]]');
    $nested_paragraphs_type = [];
    foreach ($nested_paragraphs as $nested_paragraph) {
      $nested_paragraphs_type[] = $nested_paragraph
        ->getText();
    }
    $this
      ->assertEquals([
      'test_2',
      'test_3',
      'test_2',
      'test_1',
      'test_3',
    ], $nested_paragraphs_type);

    // Check the Add above functionality does not affect the position of the new
    // added Paragraphs when using the Add Paragraph button at the bottom.
    $this
      ->drupalGet('node/add/test_modal_delta');

    // Add a new Paragraph.
    $page
      ->find('xpath', '//*[@name="button_add_modal"]')
      ->click();
    $paragraphs_dialog = $this
      ->assertSession()
      ->waitForElementVisible('css', 'div.ui-dialog');
    $paragraphs_dialog
      ->find('xpath', '//*[contains(@class, "paragraphs-add-dialog") and contains(@class, "ui-dialog-content")]//*[contains(@name, "test_1")]')
      ->press();
    $this
      ->assertSession()
      ->assertWaitOnAjaxRequest();

    // Attempt to add a new Paragraph above and cancel.
    $page
      ->find('xpath', '//*[@name="button_add_modal"]')
      ->click();
    $this
      ->getSession()
      ->executeScript("jQuery('input.paragraph-type-add-delta').first().val(0)");
    $this
      ->assertSession()
      ->elementExists('css', '.ui-dialog-titlebar-close')
      ->press();
    $delta = $this
      ->getSession()
      ->evaluateScript("jQuery('.paragraph-type-add-delta').val()");
    $this
      ->assertEquals($delta, '');

    // Add a new Paragraph with the Add button at the bottom.
    $page
      ->find('xpath', '//*[@name="button_add_modal"]')
      ->click();
    $paragraphs_dialog = $this
      ->assertSession()
      ->waitForElementVisible('css', 'div.ui-dialog');
    $paragraphs_dialog
      ->find('xpath', '//*[contains(@class, "paragraphs-add-dialog") and contains(@class, "ui-dialog-content")]//*[contains(@name, "test_2")]')
      ->press();
    $this
      ->assertSession()
      ->assertWaitOnAjaxRequest();

    // The position of it should be below the first added Paragraph.
    $base_paragraphs = $page
      ->findAll('xpath', '//*[contains(@class, "paragraph-type-label") and not(ancestor::div[contains(@class, "paragraphs-nested")])]');
    $base_paragraphs_type = [];
    foreach ($base_paragraphs as $base_paragraph) {
      $base_paragraphs_type[] = $base_paragraph
        ->getText();
    }
    $this
      ->assertEquals([
      'test_1',
      'test_2',
    ], $base_paragraphs_type);
  }

}

Members

Namesort descending Modifiers Type Description Overrides
LoginAdminTrait::$admin_user protected property Drupal user object created by loginAsAdmin().
LoginAdminTrait::loginAsAdmin public function Creates an user with admin permissions and log in.
ParagraphsAddWidgetTest::$defaultTheme protected property
ParagraphsAddWidgetTest::$modules protected static property Modules to enable.
ParagraphsAddWidgetTest::setUp protected function
ParagraphsAddWidgetTest::testAddWidgetButton public function Tests the add widget button with modal form.
ParagraphsAddWidgetTest::testModalAddWidgetDelta public function Test Modal add widget with hidden delta field.
ParagraphsCoreVersionUiTestTrait::placeDefaultBlocks protected function Places commonly used blocks in a consistent order. 1
ParagraphsTestBaseTrait::$workflow protected property The workflow entity.
ParagraphsTestBaseTrait::addFieldtoParagraphType protected function Adds a field to a given paragraph type.
ParagraphsTestBaseTrait::addParagraphedContentType protected function Adds a content type with a Paragraphs field.
ParagraphsTestBaseTrait::addParagraphsField protected function Adds a Paragraphs field to a given entity type.
ParagraphsTestBaseTrait::addParagraphsType protected function Adds a Paragraphs type.
ParagraphsTestBaseTrait::addParagraphsTypeIcon protected function Adds an icon to a paragraphs type.
ParagraphsTestBaseTrait::coreVersion protected function Checks the core version.
ParagraphsTestBaseTrait::createEditorialWorkflow protected function Creates a workflow entity.
ParagraphsTestBaseTrait::setParagraphsWidgetSettings protected function Sets some of the settings of a paragraphs field widget.