Chris@18: lockHttpClientToFixtures(); Chris@18: } Chris@18: Chris@18: /** Chris@18: * Tests all media sources in one method. Chris@18: * Chris@18: * This prevents installing the standard profile for every test case and Chris@18: * increases the performance of this test. Chris@18: */ Chris@18: public function testMediaSources() { Chris@18: $storage = FieldStorageConfig::create([ Chris@18: 'entity_type' => 'node', Chris@18: 'field_name' => 'field_related_media', Chris@18: 'type' => 'entity_reference', Chris@18: 'settings' => [ Chris@18: 'target_type' => 'media', Chris@18: ], Chris@18: ]); Chris@18: $storage->save(); Chris@18: Chris@18: FieldConfig::create([ Chris@18: 'field_storage' => $storage, Chris@18: 'entity_type' => 'node', Chris@18: 'bundle' => 'article', Chris@18: 'label' => 'Related media', Chris@18: 'settings' => [ Chris@18: 'handler_settings' => [ Chris@18: 'target_bundles' => [ Chris@18: 'image' => 'image', Chris@18: 'video' => 'video', Chris@18: 'remote_video' => 'remote_video', Chris@18: 'audio' => 'audio', Chris@18: 'file' => 'file', Chris@18: ], Chris@18: ], Chris@18: ], Chris@18: ])->save(); Chris@18: Chris@18: $display = EntityViewDisplay::load('node.article.default'); Chris@18: $display->setComponent('field_related_media', [ Chris@18: 'type' => 'entity_reference_entity_view', Chris@18: 'settings' => [ Chris@18: 'view_mode' => 'full', Chris@18: ], Chris@18: ])->save(); Chris@18: Chris@18: $this->audioTest(); Chris@18: $this->fileTest(); Chris@18: $this->imageTest(); Chris@18: $this->remoteVideoTest(); Chris@18: $this->videoTest(); Chris@18: } Chris@18: Chris@18: /** Chris@18: * Test the standard profile configuration for media type 'audio'. Chris@18: */ Chris@18: protected function audioTest() { Chris@18: $assert_session = $this->assertSession(); Chris@18: $page = $this->getSession()->getPage(); Chris@18: $source_field_id = 'field_media_audio_file'; Chris@18: Chris@18: // Create 2 test files. Chris@18: $test_filename = $this->randomMachineName() . '.mp3'; Chris@18: $test_filepath = 'public://' . $test_filename; Chris@18: $test_filename_updated = $this->randomMachineName() . '.mp3'; Chris@18: $test_filepath_updated = 'public://' . $test_filename_updated; Chris@18: file_put_contents($test_filepath, str_repeat('t', 10)); Chris@18: file_put_contents($test_filepath_updated, str_repeat('u', 10)); Chris@18: Chris@18: // Check if the name field is properly hidden on the media form. Chris@18: $this->drupalGet('media/add/audio'); Chris@18: $assert_session->fieldNotExists('name'); Chris@18: Chris@18: // Check if the source field is available. Chris@18: $assert_session->fieldExists("files[{$source_field_id}_0]"); Chris@18: Chris@18: // Create a media item. Chris@18: $page->attachFileToField("files[{$source_field_id}_0]", \Drupal::service('file_system')->realpath($test_filepath)); Chris@18: $result = $assert_session->waitForButton('Remove'); Chris@18: $this->assertNotEmpty($result); Chris@18: $page->pressButton('Save'); Chris@18: $audio_media_id = $this->container Chris@18: ->get('entity_type.manager') Chris@18: ->getStorage('media') Chris@18: ->getQuery() Chris@18: ->sort('mid', 'DESC') Chris@18: ->execute(); Chris@18: $audio_media_id = reset($audio_media_id); Chris@18: Chris@18: // Reference the created media using an entity_reference field and make sure Chris@18: // the output is what we expect. Chris@18: $node = Node::create([ Chris@18: 'title' => 'Host node', Chris@18: 'type' => 'article', Chris@18: 'field_related_media' => [ Chris@18: 'target_id' => $audio_media_id, Chris@18: ], Chris@18: ]); Chris@18: $node->save(); Chris@18: Chris@18: $this->drupalGet('/node/' . $node->id()); Chris@18: Chris@18: // Check if the default media name is generated as expected. Chris@18: $media = \Drupal::entityTypeManager()->getStorage('media')->loadUnchanged($audio_media_id); Chris@18: $this->assertSame($test_filename, $media->label()); Chris@18: Chris@18: // Here we expect to see only the linked filename. Assert only one element Chris@18: // in the content region. Chris@18: $assert_session->elementsCount('css', 'article.media--type-audio > *', 1); Chris@18: Chris@18: // Assert the audio file is present inside the media element and that its Chris@18: // src attribute matches the audio file. Chris@18: $audio_element = $assert_session->elementExists('css', 'article.media--type-audio .field--name-field-media-audio-file audio > source'); Chris@18: $expected_audio_src = file_url_transform_relative(file_create_url(\Drupal::token()->replace('public://[date:custom:Y]-[date:custom:m]/' . $test_filename))); Chris@18: $this->assertSame($expected_audio_src, $audio_element->getAttribute('src')); Chris@18: Chris@18: // Assert the media name is updated through the field mapping when changing Chris@18: // the source field. Chris@18: $this->drupalGet('media/' . $audio_media_id . '/edit'); Chris@18: $page->pressButton('Remove'); Chris@18: $result = $assert_session->waitForField("files[{$source_field_id}_0]"); Chris@18: $this->assertNotEmpty($result); Chris@18: $page->attachFileToField("files[{$source_field_id}_0]", \Drupal::service('file_system')->realpath($test_filepath_updated)); Chris@18: $result = $assert_session->waitForButton('Remove'); Chris@18: $this->assertNotEmpty($result); Chris@18: $page->pressButton('Save'); Chris@18: Chris@18: $this->drupalGet('/node/' . $node->id()); Chris@18: Chris@18: // Check if the default media name is updated as expected. Chris@18: $media = \Drupal::entityTypeManager()->getStorage('media')->loadUnchanged($audio_media_id); Chris@18: $this->assertSame($test_filename_updated, $media->label()); Chris@18: Chris@18: // Again we expect to see only the linked filename. Assert only one element Chris@18: // in the content region. Chris@18: $assert_session->elementsCount('css', 'article.media--type-audio > *', 1); Chris@18: Chris@18: // Assert the audio file is present inside the media element and that its Chris@18: // src attribute matches the updated audio file. Chris@18: $audio_element = $assert_session->elementExists('css', 'article.media--type-audio .field--name-field-media-audio-file audio > source'); Chris@18: $expected_audio_src = file_url_transform_relative(file_create_url(\Drupal::token()->replace('public://[date:custom:Y]-[date:custom:m]/' . $test_filename_updated))); Chris@18: $this->assertSame($expected_audio_src, $audio_element->getAttribute('src')); Chris@18: } Chris@18: Chris@18: /** Chris@18: * Test the standard profile configuration for media type 'image'. Chris@18: */ Chris@18: protected function imageTest() { Chris@18: $assert_session = $this->assertSession(); Chris@18: $page = $this->getSession()->getPage(); Chris@18: $source_field_id = 'field_media_image'; Chris@18: Chris@18: // Check if the name field is properly hidden on the media form. Chris@18: $this->drupalGet('media/add/image'); Chris@18: $assert_session->fieldNotExists('name'); Chris@18: Chris@18: // Check if the source field is available. Chris@18: $assert_session->fieldExists("files[{$source_field_id}_0]"); Chris@18: Chris@18: // Create a media item. Chris@18: $image_media_name = 'example_1.jpeg'; Chris@18: $page->attachFileToField("files[{$source_field_id}_0]", $this->root . '/core/modules/media/tests/fixtures/' . $image_media_name); Chris@18: $result = $assert_session->waitForButton('Remove'); Chris@18: $this->assertNotEmpty($result); Chris@18: $page->fillField("{$source_field_id}[0][alt]", 'Image Alt Text 1'); Chris@18: $page->pressButton('Save'); Chris@18: $image_media_id = $this->container Chris@18: ->get('entity_type.manager') Chris@18: ->getStorage('media') Chris@18: ->getQuery() Chris@18: ->sort('mid', 'DESC') Chris@18: ->execute(); Chris@18: $image_media_id = reset($image_media_id); Chris@18: Chris@18: // Reference the created media using an entity_reference field and make sure Chris@18: // the output is what we expect. Chris@18: $node = Node::create([ Chris@18: 'title' => 'Host node', Chris@18: 'type' => 'article', Chris@18: 'field_related_media' => [ Chris@18: 'target_id' => $image_media_id, Chris@18: ], Chris@18: ]); Chris@18: $node->save(); Chris@18: Chris@18: $this->drupalGet('/node/' . $node->id()); Chris@18: Chris@18: // Check if the default media name is generated as expected. Chris@18: $media = \Drupal::entityTypeManager()->getStorage('media')->loadUnchanged($image_media_id); Chris@18: $this->assertSame($image_media_name, $media->label()); Chris@18: Chris@18: // Here we expect to see only the image, nothing else. Assert only one Chris@18: // element in the content region. Chris@18: $assert_session->elementsCount('css', 'article.media--type-image > *', 1); Chris@18: Chris@18: // Assert the image element is present inside the media element and that its Chris@18: // src attribute matches the image. Chris@18: $image_element = $assert_session->elementExists('css', 'article.media--type-image img'); Chris@18: $expected_image_src = file_url_transform_relative(file_create_url(\Drupal::token()->replace('public://[date:custom:Y]-[date:custom:m]/' . $image_media_name))); Chris@18: $this->assertSame($expected_image_src, $image_element->getAttribute('src')); Chris@18: Chris@18: // Assert the media name is updated through the field mapping when changing Chris@18: // the source field. Chris@18: $this->drupalGet('media/' . $image_media_id . '/edit'); Chris@18: $page->pressButton('Remove'); Chris@18: $result = $assert_session->waitForField("files[{$source_field_id}_0]"); Chris@18: $this->assertNotEmpty($result); Chris@18: $image_media_name_updated = 'example_2.jpeg'; Chris@18: $page->attachFileToField("files[{$source_field_id}_0]", $this->root . '/core/modules/media/tests/fixtures/' . $image_media_name_updated); Chris@18: $result = $assert_session->waitForButton('Remove'); Chris@18: $this->assertNotEmpty($result); Chris@18: $page->fillField("{$source_field_id}[0][alt]", 'Image Alt Text 2'); Chris@18: $page->pressButton('Save'); Chris@18: Chris@18: $this->drupalGet('/node/' . $node->id()); Chris@18: Chris@18: // Check if the default media name is updated as expected. Chris@18: $media = \Drupal::entityTypeManager()->getStorage('media')->loadUnchanged($image_media_id); Chris@18: $this->assertSame($image_media_name_updated, $media->label()); Chris@18: Chris@18: // Again we expect to see only the image, nothing else. Assert only one Chris@18: // element in the content region. Chris@18: $assert_session->elementsCount('css', 'article.media--type-image > *', 1); Chris@18: Chris@18: // Assert the image element is present inside the media element and that its Chris@18: // src attribute matches the updated image. Chris@18: $image_element = $assert_session->elementExists('css', 'article.media--type-image img'); Chris@18: $expected_image_src = file_url_transform_relative(file_create_url(\Drupal::token()->replace('public://[date:custom:Y]-[date:custom:m]/' . $image_media_name_updated))); Chris@18: $this->assertSame($expected_image_src, $image_element->getAttribute('src')); Chris@18: } Chris@18: Chris@18: /** Chris@18: * Test the standard profile configuration for media type 'file'. Chris@18: */ Chris@18: protected function fileTest() { Chris@18: $assert_session = $this->assertSession(); Chris@18: $page = $this->getSession()->getPage(); Chris@18: $source_field_id = 'field_media_file'; Chris@18: Chris@18: // Create 2 test files. Chris@18: $test_filename = $this->randomMachineName() . '.txt'; Chris@18: $test_filepath = 'public://' . $test_filename; Chris@18: $test_filename_updated = $this->randomMachineName() . '.txt'; Chris@18: $test_filepath_updated = 'public://' . $test_filename_updated; Chris@18: file_put_contents($test_filepath, $this->randomMachineName()); Chris@18: file_put_contents($test_filepath_updated, $this->randomMachineName()); Chris@18: Chris@18: // Check if the name field is properly hidden on the media form. Chris@18: $this->drupalGet('media/add/file'); Chris@18: $assert_session->fieldNotExists('name'); Chris@18: Chris@18: // Check if the source field is available. Chris@18: $assert_session->fieldExists("files[{$source_field_id}_0]"); Chris@18: Chris@18: // Create a media item. Chris@18: $page->attachFileToField("files[{$source_field_id}_0]", \Drupal::service('file_system')->realpath($test_filepath)); Chris@18: $result = $assert_session->waitForButton('Remove'); Chris@18: $this->assertNotEmpty($result); Chris@18: $page->pressButton('Save'); Chris@18: $file_media_id = $this->container Chris@18: ->get('entity_type.manager') Chris@18: ->getStorage('media') Chris@18: ->getQuery() Chris@18: ->sort('mid', 'DESC') Chris@18: ->execute(); Chris@18: $file_media_id = reset($file_media_id); Chris@18: Chris@18: // Reference the created media using an entity_reference field and make sure Chris@18: // the output is what we expect. Chris@18: $node = Node::create([ Chris@18: 'title' => 'Host node', Chris@18: 'type' => 'article', Chris@18: 'field_related_media' => [ Chris@18: 'target_id' => $file_media_id, Chris@18: ], Chris@18: ]); Chris@18: $node->save(); Chris@18: Chris@18: $this->drupalGet('/node/' . $node->id()); Chris@18: Chris@18: // Check if the default media name is generated as expected. Chris@18: $media = \Drupal::entityTypeManager()->getStorage('media')->loadUnchanged($file_media_id); Chris@18: $this->assertSame($test_filename, $media->label()); Chris@18: Chris@18: // Here we expect to see only the linked filename. Assert only one element Chris@18: // in the content region. Chris@18: $assert_session->elementsCount('css', 'article.media--type-file > *', 1); Chris@18: Chris@18: // Assert the file link is present in the media element and its text matches Chris@18: // the filename. Chris@18: $link_element = $assert_session->elementExists('css', 'article.media--type-file .field--name-field-media-file a'); Chris@18: $this->assertSame($test_filename, $link_element->getText()); Chris@18: Chris@18: // Assert the media name is updated through the field mapping when changing Chris@18: // the source field. Chris@18: $this->drupalGet('media/' . $file_media_id . '/edit'); Chris@18: $page->pressButton('Remove'); Chris@18: $result = $assert_session->waitForField("files[{$source_field_id}_0]"); Chris@18: $this->assertNotEmpty($result); Chris@18: $page->attachFileToField("files[{$source_field_id}_0]", \Drupal::service('file_system')->realpath($test_filepath_updated)); Chris@18: $result = $assert_session->waitForButton('Remove'); Chris@18: $this->assertNotEmpty($result); Chris@18: $page->pressButton('Save'); Chris@18: Chris@18: $this->drupalGet('/node/' . $node->id()); Chris@18: Chris@18: // Check if the default media name is updated as expected. Chris@18: $media = \Drupal::entityTypeManager()->getStorage('media')->loadUnchanged($file_media_id); Chris@18: $this->assertSame($test_filename_updated, $media->label()); Chris@18: Chris@18: // Again we expect to see only the linked filename. Assert only one element Chris@18: // in the content region. Chris@18: $assert_session->elementsCount('css', 'article.media--type-file > *', 1); Chris@18: Chris@18: // Assert the file link is present in the media element and its text matches Chris@18: // the updated filename. Chris@18: $link_element = $assert_session->elementExists('css', 'article.media--type-file .field--name-field-media-file a'); Chris@18: $this->assertSame($test_filename_updated, $link_element->getText()); Chris@18: } Chris@18: Chris@18: /** Chris@18: * Test the standard profile configuration for media type 'remote_video'. Chris@18: */ Chris@18: protected function remoteVideoTest() { Chris@18: $assert_session = $this->assertSession(); Chris@18: $page = $this->getSession()->getPage(); Chris@18: $source_field_id = 'field_media_oembed_video'; Chris@18: Chris@18: // Set video fixtures. Chris@18: $video_title = 'Drupal Rap Video - Schipulcon09'; Chris@18: $video_url = 'https://vimeo.com/7073899'; Chris@18: ResourceController::setResourceUrl($video_url, $this->getFixturesDirectory() . '/video_vimeo.json'); Chris@18: $video_title_updated = "Everyday I'm Drupalin' Drupal Rap (Rick Ross - Hustlin)"; Chris@18: $video_url_updated = 'https://www.youtube.com/watch?v=PWjcqE3QKBg'; Chris@18: ResourceController::setResourceUrl($video_url_updated, $this->getFixturesDirectory() . '/video_youtube.json'); Chris@18: Chris@18: // Check if the name field is properly hidden on the media form. Chris@18: $this->drupalGet('media/add/remote_video'); Chris@18: $assert_session->fieldNotExists('name'); Chris@18: Chris@18: // Check if the source field is available. Chris@18: $assert_session->fieldExists("{$source_field_id}[0][value]"); Chris@18: Chris@18: // Create a media item. Chris@18: $page->fillField("{$source_field_id}[0][value]", $video_url); Chris@18: $page->pressButton('Save'); Chris@18: $remote_video_media_id = $this->container Chris@18: ->get('entity_type.manager') Chris@18: ->getStorage('media') Chris@18: ->getQuery() Chris@18: ->sort('mid', 'DESC') Chris@18: ->execute(); Chris@18: $remote_video_media_id = reset($remote_video_media_id); Chris@18: Chris@18: // Reference the created media using an entity_reference field and make sure Chris@18: // the output is what we expect. Chris@18: $node = Node::create([ Chris@18: 'title' => 'Host node', Chris@18: 'type' => 'article', Chris@18: 'field_related_media' => [ Chris@18: 'target_id' => $remote_video_media_id, Chris@18: ], Chris@18: ]); Chris@18: $node->save(); Chris@18: Chris@18: $this->drupalGet('/node/' . $node->id()); Chris@18: Chris@18: // Check if the default media name is generated as expected. Chris@18: $media = \Drupal::entityTypeManager()->getStorage('media')->loadUnchanged($remote_video_media_id); Chris@18: $this->assertSame($video_title, $media->label()); Chris@18: Chris@18: // Here we expect to see only the video iframe. Assert only one element in Chris@18: // the content region. Chris@18: $assert_session->elementsCount('css', 'article.media--type-remote-video > *', 1); Chris@18: Chris@18: // Assert the iframe is present in the media element and its src attribute Chris@18: // matches the URL and query parameters. Chris@18: $iframe_url = $assert_session->elementExists('css', 'article.media--type-remote-video .field--name-field-media-oembed-video iframe')->getAttribute('src'); Chris@18: $iframe_url = parse_url($iframe_url); Chris@18: $this->assertStringEndsWith('/media/oembed', $iframe_url['path']); Chris@18: $this->assertNotEmpty($iframe_url['query']); Chris@18: $query = []; Chris@18: parse_str($iframe_url['query'], $query); Chris@18: $this->assertSame($video_url, $query['url']); Chris@18: $this->assertNotEmpty($query['hash']); Chris@18: Chris@18: // Assert the media name is updated through the field mapping when changing Chris@18: // the source field. Chris@18: $this->drupalGet('media/' . $remote_video_media_id . '/edit'); Chris@18: $page->fillField("{$source_field_id}[0][value]", $video_url_updated); Chris@18: $page->pressButton('Save'); Chris@18: Chris@18: $this->drupalGet('/node/' . $node->id()); Chris@18: Chris@18: // Check if the default media name is updated as expected. Chris@18: $media = \Drupal::entityTypeManager()->getStorage('media')->loadUnchanged($remote_video_media_id); Chris@18: $this->assertSame($video_title_updated, $media->label()); Chris@18: Chris@18: // Again we expect to see only the video iframe. Assert only one element in Chris@18: // the content region. Chris@18: $assert_session->elementsCount('css', 'article.media--type-remote-video > *', 1); Chris@18: Chris@18: // Assert the iframe is present in the media element and its src attribute Chris@18: // matches the updated URL and query parameters. Chris@18: $iframe_url = $assert_session->elementExists('css', 'article.media--type-remote-video .field--name-field-media-oembed-video iframe')->getAttribute('src'); Chris@18: $iframe_url = parse_url($iframe_url); Chris@18: $this->assertStringEndsWith('/media/oembed', $iframe_url['path']); Chris@18: $this->assertNotEmpty($iframe_url['query']); Chris@18: $query = []; Chris@18: parse_str($iframe_url['query'], $query); Chris@18: $this->assertSame($video_url_updated, $query['url']); Chris@18: $this->assertNotEmpty($query['hash']); Chris@18: } Chris@18: Chris@18: /** Chris@18: * Test the standard profile configuration for media type 'video'. Chris@18: */ Chris@18: protected function videoTest() { Chris@18: $assert_session = $this->assertSession(); Chris@18: $page = $this->getSession()->getPage(); Chris@18: $source_field_id = 'field_media_video_file'; Chris@18: Chris@18: // Create 2 test files. Chris@18: $test_filename = $this->randomMachineName() . '.mp4'; Chris@18: $test_filepath = 'public://' . $test_filename; Chris@18: $test_filename_updated = $this->randomMachineName() . '.mp4'; Chris@18: $test_filepath_updated = 'public://' . $test_filename_updated; Chris@18: file_put_contents($test_filepath, str_repeat('t', 10)); Chris@18: file_put_contents($test_filepath_updated, str_repeat('u', 10)); Chris@18: Chris@18: // Check if the name field is properly hidden on the media form. Chris@18: $this->drupalGet('media/add/video'); Chris@18: $assert_session->fieldNotExists('name'); Chris@18: Chris@18: // Check if the source field is available. Chris@18: $assert_session->fieldExists("files[{$source_field_id}_0]"); Chris@18: Chris@18: // Create a media item. Chris@18: $page->attachFileToField("files[{$source_field_id}_0]", \Drupal::service('file_system')->realpath($test_filepath)); Chris@18: $result = $assert_session->waitForButton('Remove'); Chris@18: $this->assertNotEmpty($result); Chris@18: $page->pressButton('Save'); Chris@18: $video_media_id = $this->container Chris@18: ->get('entity_type.manager') Chris@18: ->getStorage('media') Chris@18: ->getQuery() Chris@18: ->sort('mid', 'DESC') Chris@18: ->execute(); Chris@18: $video_media_id = reset($video_media_id); Chris@18: Chris@18: // Reference the created media using an entity_reference field and make sure Chris@18: // the output is what we expect. Chris@18: $node = Node::create([ Chris@18: 'title' => 'Host node', Chris@18: 'type' => 'article', Chris@18: 'field_related_media' => [ Chris@18: 'target_id' => $video_media_id, Chris@18: ], Chris@18: ]); Chris@18: $node->save(); Chris@18: Chris@18: $this->drupalGet('/node/' . $node->id()); Chris@18: Chris@18: // Check if the default media name is generated as expected. Chris@18: $media = \Drupal::entityTypeManager()->getStorage('media')->loadUnchanged($video_media_id); Chris@18: $this->assertSame($test_filename, $media->label()); Chris@18: Chris@18: // Here we expect to see only the linked filename. Assert only one element Chris@18: // in the content region. Chris@18: $assert_session->elementsCount('css', 'article.media--type-video > *', 1); Chris@18: Chris@18: // Assert the video element is present inside the media element and that its Chris@18: // src attribute matches the video file. Chris@18: $video_element = $assert_session->elementExists('css', 'article.media--type-video .field--name-field-media-video-file video > source'); Chris@18: $expected_video_src = file_url_transform_relative(file_create_url(\Drupal::token()->replace('public://[date:custom:Y]-[date:custom:m]/' . $test_filename))); Chris@18: $this->assertSame($expected_video_src, $video_element->getAttribute('src')); Chris@18: Chris@18: // Assert the media name is updated through the field mapping when changing Chris@18: // the source field. Chris@18: $this->drupalGet('media/' . $video_media_id . '/edit'); Chris@18: $page->pressButton('Remove'); Chris@18: $result = $assert_session->waitForField("files[{$source_field_id}_0]"); Chris@18: $this->assertNotEmpty($result); Chris@18: $page->attachFileToField("files[{$source_field_id}_0]", \Drupal::service('file_system')->realpath($test_filepath_updated)); Chris@18: $result = $assert_session->waitForButton('Remove'); Chris@18: $this->assertNotEmpty($result); Chris@18: $page->pressButton('Save'); Chris@18: Chris@18: $this->drupalGet('/node/' . $node->id()); Chris@18: Chris@18: // Check if the default media name is updated as expected. Chris@18: $media = \Drupal::entityTypeManager()->getStorage('media')->loadUnchanged($video_media_id); Chris@18: $this->assertSame($test_filename_updated, $media->label()); Chris@18: Chris@18: // Again we expect to see only the linked filename. Assert only one element Chris@18: // in the content region. Chris@18: $assert_session->elementsCount('css', 'article.media--type-video > *', 1); Chris@18: Chris@18: // Assert the video element is present inside the media element and that its Chris@18: // src attribute matches the updated video file. Chris@18: $video_element = $assert_session->elementExists('css', 'article.media--type-video .field--name-field-media-video-file video > source'); Chris@18: $expected_video_src = file_url_transform_relative(file_create_url(\Drupal::token()->replace('public://[date:custom:Y]-[date:custom:m]/' . $test_filename_updated))); Chris@18: $this->assertSame($expected_video_src, $video_element->getAttribute('src')); Chris@18: } Chris@18: Chris@18: }