diff --git a/core/modules/block/src/Tests/BlockLanguageCacheTest.php b/core/modules/block/src/Tests/BlockLanguageCacheTest.php index 543e65e..a11bdd6 100644 --- a/core/modules/block/src/Tests/BlockLanguageCacheTest.php +++ b/core/modules/block/src/Tests/BlockLanguageCacheTest.php @@ -62,7 +62,7 @@ public function testBlockLinks() { // Create the block cache for all languages. foreach ($this->langcodes as $langcode) { $this->drupalGet('admin/structure/block', array('language' => $langcode)); - $this->clickLink('Place block'); + $this->clickLinkPartialName('Place block'); } // Create a menu in the default language. @@ -74,7 +74,7 @@ public function testBlockLinks() { // Check that the block is listed for all languages. foreach ($this->langcodes as $langcode) { $this->drupalGet('admin/structure/block', array('language' => $langcode)); - $this->clickLink('Place block'); + $this->clickLinkPartialName('Place block'); $this->assertText($edit['label']); } } diff --git a/core/modules/block/src/Tests/BlockUiTest.php b/core/modules/block/src/Tests/BlockUiTest.php index 1f26739..37fce6e 100644 --- a/core/modules/block/src/Tests/BlockUiTest.php +++ b/core/modules/block/src/Tests/BlockUiTest.php @@ -146,7 +146,7 @@ public function testCandidateBlockList() { $pattern = '//tr[.//td/div[text()=:title] and .//td[text()=:category] and .//td//a[contains(@href, :href)]]'; $this->drupalGet('admin/structure/block'); - $this->clickLink('Place block'); + $this->clickLinkPartialName('Place block'); $elements = $this->xpath($pattern, $arguments); $this->assertTrue(!empty($elements), 'The test block appears in the category for its module.'); @@ -155,7 +155,7 @@ public function testCandidateBlockList() { $this->container->get('plugin.manager.block')->clearCachedDefinitions(); $this->drupalGet('admin/structure/block'); - $this->clickLink('Place block'); + $this->clickLinkPartialName('Place block'); $arguments[':category'] = 'Custom category'; $elements = $this->xpath($pattern, $arguments); $this->assertTrue(!empty($elements), 'The test block appears in a custom category controlled by block_test_block_alter().'); diff --git a/core/modules/block/src/Tests/BlockXssTest.php b/core/modules/block/src/Tests/BlockXssTest.php index 0baa67f..3d9bfd3 100644 --- a/core/modules/block/src/Tests/BlockXssTest.php +++ b/core/modules/block/src/Tests/BlockXssTest.php @@ -51,7 +51,7 @@ public function testXssInCategory() { $this->drupalPlaceBlock('test_xss_title'); $this->drupalLogin($this->drupalCreateUser(['administer blocks', 'access administration pages'])); $this->drupalGet(Url::fromRoute('block.admin_display')); - $this->clickLink('Place block'); + $this->clickLinkPartialName('Place block'); $this->assertNoRaw(""); } @@ -78,7 +78,7 @@ protected function doViewTest() { $view->save(); $this->drupalGet(Url::fromRoute('block.admin_display')); - $this->clickLink('Place block'); + $this->clickLinkPartialName('Place block'); // The block admin label is automatically XSS admin filtered. $this->assertRaw('alert("view");'); $this->assertNoRaw(''); @@ -94,7 +94,7 @@ protected function doMenuTest() { ])->save(); $this->drupalGet(Url::fromRoute('block.admin_display')); - $this->clickLink('Place block'); + $this->clickLinkPartialName('Place block'); // The block admin label is automatically XSS admin filtered. $this->assertRaw('alert("menu");'); $this->assertNoRaw(''); @@ -115,7 +115,7 @@ protected function doBlockContentTest() { ])->save(); $this->drupalGet(Url::fromRoute('block.admin_display')); - $this->clickLink('Place block'); + $this->clickLinkPartialName('Place block'); // The block admin label is automatically XSS admin filtered. $this->assertRaw('alert("block_content");'); $this->assertNoRaw(''); diff --git a/core/modules/block/src/Tests/Views/DisplayBlockTest.php b/core/modules/block/src/Tests/Views/DisplayBlockTest.php index d9f9196..880f68c 100644 --- a/core/modules/block/src/Tests/Views/DisplayBlockTest.php +++ b/core/modules/block/src/Tests/Views/DisplayBlockTest.php @@ -70,7 +70,7 @@ public function testBlockCategory() { ':category' => t('Lists (Views)'), ); $this->drupalGet('admin/structure/block'); - $this->clickLink('Place block'); + $this->clickLinkPartialName('Place block'); $elements = $this->xpath($pattern, $arguments); $this->assertTrue(!empty($elements), 'The test block appears in the category for its base table.'); @@ -95,7 +95,7 @@ public function testBlockCategory() { // Test that the blocks are listed under the correct categories. $arguments[':category'] = $category; $this->drupalGet('admin/structure/block'); - $this->clickLink('Place block'); + $this->clickLinkPartialName('Place block'); $elements = $this->xpath($pattern, $arguments); $this->assertTrue(!empty($elements), 'The test block appears in the custom category.'); diff --git a/core/modules/block_content/src/Tests/BlockContentTypeTest.php b/core/modules/block_content/src/Tests/BlockContentTypeTest.php index 681c6ce..20dc1a2 100644 --- a/core/modules/block_content/src/Tests/BlockContentTypeTest.php +++ b/core/modules/block_content/src/Tests/BlockContentTypeTest.php @@ -189,7 +189,7 @@ public function testsBlockContentAddTypes() { // block configure form. $path = $theme == $default_theme ? 'admin/structure/block' : "admin/structure/block/list/$theme"; $this->drupalGet($path); - $this->clickLink('Place block'); + $this->clickLinkPartialName('Place block'); $this->clickLink(t('Add custom block')); // The seven theme has markup inside the link, we cannot use clickLink(). if ($default_theme == 'seven') { diff --git a/core/modules/menu_ui/src/Tests/MenuTest.php b/core/modules/menu_ui/src/Tests/MenuTest.php index 3c00e92..34dacc5 100644 --- a/core/modules/menu_ui/src/Tests/MenuTest.php +++ b/core/modules/menu_ui/src/Tests/MenuTest.php @@ -219,7 +219,7 @@ function addCustomMenu() { // Confirm that the custom menu block is available. $this->drupalGet('admin/structure/block/list/' . $this->config('system.theme')->get('default')); - $this->clickLink('Place block'); + $this->clickLinkPartialName('Place block'); $this->assertText($label); // Enable the block. @@ -533,7 +533,7 @@ function testSystemMenuRename() { // Make sure menu shows up with new name in block addition. $default_theme = $this->config('system.theme')->get('default'); $this->drupalget('admin/structure/block/list/' . $default_theme); - $this->clickLink('Place block'); + $this->clickLinkPartialName('Place block'); $this->assertText($edit['label']); } diff --git a/core/modules/search/src/Tests/SearchBlockTest.php b/core/modules/search/src/Tests/SearchBlockTest.php index 2348ae0..4b774a1 100644 --- a/core/modules/search/src/Tests/SearchBlockTest.php +++ b/core/modules/search/src/Tests/SearchBlockTest.php @@ -36,7 +36,7 @@ public function testSearchFormBlock() { // Test availability of the search block in the admin "Place blocks" list. $this->drupalGet('admin/structure/block'); - $this->clickLink('Place block'); + $this->clickLinkPartialName('Place block'); $this->assertLinkByHref('/admin/structure/block/add/search_form_block/classy', 0, 'Did not find the search block in block candidate list.'); diff --git a/core/modules/simpletest/src/WebTestBase.php b/core/modules/simpletest/src/WebTestBase.php index e17d703..c43888b 100644 --- a/core/modules/simpletest/src/WebTestBase.php +++ b/core/modules/simpletest/src/WebTestBase.php @@ -2324,7 +2324,7 @@ protected function handleForm(&$post, &$edit, &$upload, $submit, $form) { } /** - * Follows a link by name. + * Follows a link by complete name. * * Will click the first link found with this link text by default, or a later * one if an index is given. Match is case sensitive with normalized space. @@ -2332,17 +2332,54 @@ protected function handleForm(&$post, &$edit, &$upload, $submit, $form) { * * If the link is discovered and clicked, the test passes. Fail otherwise. * - * @param $label + * @param string $label * Text between the anchor tags. - * @param $index + * @param int $index * Link position counting from zero. * - * @return + * @return string|bool * Page contents on success, or FALSE on failure. */ protected function clickLink($label, $index = 0) { + return $this->clickLinkHelper($label, $index, '//a[normalize-space()=:label]'); + } + + /** + * Follows a link by partial name. + * + * + * If the link is discovered and clicked, the test passes. Fail otherwise. + * + * @param string $label + * Text between the anchor tags, uses starts-with(). + * @param int $index + * Link position counting from zero. + * + * @return string|bool + * Page contents on success, or FALSE on failure. + * + * @see ::clickLink() + */ + protected function clickLinkPartialName($label, $index = 0) { + return $this->clickLinkHelper($label, $index, '//a[starts-with(normalize-space(), :label)]'); + } + + /** + * Provides a helper for ::clickLink() and ::clickLinkPartialName(). + * + * @param string $label + * Text between the anchor tags, uses starts-with(). + * @param int $index + * Link position counting from zero. + * @param string $pattern + * A pattern to use for the XPath. + * + * @return bool|string + * Page contents on success, or FALSE on failure. + */ + protected function clickLinkHelper($label, $index, $pattern) { $url_before = $this->getUrl(); - $urls = $this->xpath('//a[normalize-space()=:label]', array(':label' => $label)); + $urls = $this->xpath($pattern, array(':label' => $label)); if (isset($urls[$index])) { $url_target = $this->getAbsoluteUrl($urls[$index]['href']); $this->pass(SafeMarkup::format('Clicked link %label (@url_target) from @url_before', array('%label' => $label, '@url_target' => $url_target, '@url_before' => $url_before)), 'Browser'); diff --git a/core/modules/views/src/Tests/Wizard/BasicTest.php b/core/modules/views/src/Tests/Wizard/BasicTest.php index 2ba0dac..fe736de 100644 --- a/core/modules/views/src/Tests/Wizard/BasicTest.php +++ b/core/modules/views/src/Tests/Wizard/BasicTest.php @@ -133,7 +133,7 @@ function testViewsWizardAndListing() { // Confirm that the block is available in the block administration UI. $this->drupalGet('admin/structure/block/list/' . $this->config('system.theme')->get('default')); - $this->clickLink('Place block'); + $this->clickLinkPartialName('Place block'); $this->assertText($view3['label']); // Place the block. diff --git a/core/modules/views/src/Tests/Wizard/ItemsPerPageTest.php b/core/modules/views/src/Tests/Wizard/ItemsPerPageTest.php index 7fd06d0..132df58 100644 --- a/core/modules/views/src/Tests/Wizard/ItemsPerPageTest.php +++ b/core/modules/views/src/Tests/Wizard/ItemsPerPageTest.php @@ -71,7 +71,7 @@ function testItemsPerPage() { // Confirm that the block is listed in the block administration UI. $this->drupalGet('admin/structure/block/list/' . $this->config('system.theme')->get('default')); - $this->clickLink('Place block'); + $this->clickLinkPartialName('Place block'); $this->assertText($view['label']); // Place the block, visit a page that displays the block, and check that the diff --git a/core/modules/views_ui/src/Tests/OverrideDisplaysTest.php b/core/modules/views_ui/src/Tests/OverrideDisplaysTest.php index 15b6c88..2a693f7 100644 --- a/core/modules/views_ui/src/Tests/OverrideDisplaysTest.php +++ b/core/modules/views_ui/src/Tests/OverrideDisplaysTest.php @@ -50,7 +50,7 @@ function testOverrideDisplays() { // Confirm that the view block is available in the block administration UI. $this->drupalGet('admin/structure/block/list/' . $this->config('system.theme')->get('default')); - $this->clickLink('Place block'); + $this->clickLinkPartialName('Place block'); $this->assertText($view['label']); // Place the block. @@ -110,7 +110,7 @@ function testWizardMixedDefaultOverriddenDisplays() { // Confirm that the block is available in the block administration UI. $this->drupalGet('admin/structure/block/list/' . $this->config('system.theme')->get('default')); - $this->clickLink('Place block'); + $this->clickLinkPartialName('Place block'); $this->assertText($view['label']); // Put the block into the first sidebar region, and make sure it will not