summaryrefslogtreecommitdiff
path: root/modules
diff options
context:
space:
mode:
authorDries Buytaert <dries@buytaert.net>2010-03-31 20:05:06 +0000
committerDries Buytaert <dries@buytaert.net>2010-03-31 20:05:06 +0000
commit6fc055ab906c035355bfb789aed404551db5b45a (patch)
treef29650c65f8a7003ce73ebc6047f216f91e14c79 /modules
parente0871ec49bb81adff156d4bc7cf2d9f8b50d04a0 (diff)
downloadbrdo-6fc055ab906c035355bfb789aed404551db5b45a.tar.gz
brdo-6fc055ab906c035355bfb789aed404551db5b45a.tar.bz2
- Patch #730220 by Berdir, aspilicious, Damien Tournoud, pwolanin: improved xpath tests.
Diffstat (limited to 'modules')
-rw-r--r--modules/block/block.test9
-rw-r--r--modules/book/book.test2
-rw-r--r--modules/comment/comment.test40
-rw-r--r--modules/field/modules/options/options.test4
-rw-r--r--modules/filter/filter.test10
-rw-r--r--modules/locale/locale.test15
-rw-r--r--modules/node/node.test3
-rw-r--r--modules/rdf/rdf.test52
-rw-r--r--modules/simpletest/drupal_web_test_case.php70
-rw-r--r--modules/simpletest/simpletest.test30
-rw-r--r--modules/syslog/syslog.test2
-rw-r--r--modules/translation/translation.test2
12 files changed, 169 insertions, 70 deletions
diff --git a/modules/block/block.test b/modules/block/block.test
index 19f52d970..79b6b19ef 100644
--- a/modules/block/block.test
+++ b/modules/block/block.test
@@ -58,7 +58,7 @@ class BlockTestCase extends DrupalWebTestCase {
foreach ($themes as $key => $theme) {
if ($theme->status) {
foreach ($theme->info['regions_hidden'] as $hidden_region) {
- $elements = $this->xpath('//select[@id="edit-regions-' . $key . '"]//option[@value="' . $hidden_region . '"]');
+ $elements = $this->xpath('//select[@id=:id]//option[@value=:value]', array(':id' => 'edit-regions-' . $key, ':value' => $hidden_region));
$this->assertFalse(isset($elements[0]), t('The hidden region @region is not available for @theme.', array('@region' => $hidden_region, '@theme' => $key)));
}
}
@@ -220,7 +220,7 @@ class BlockTestCase extends DrupalWebTestCase {
$this->assertNoText(t($block['title']), t('Block no longer appears on page.'));
// Confirm that the regions xpath is not availble
- $xpath = '//div[@id="block-block-' . $bid . '"]/*';
+ $xpath = $this->buildXPathQuery('//div[@id=:id]/*', array(':id' => 'block-block-' . $bid));
$this->assertNoFieldByXPath($xpath, FALSE, t('Custom block found in no regions.'));
// For convenience of developers, put the navigation block back.
@@ -252,7 +252,10 @@ class BlockTestCase extends DrupalWebTestCase {
$this->assertText(t($block['title']), t('Block successfully being displayed on the page.'));
// Confirm that the custom block was found at the proper region.
- $xpath = '//div[@class="' . $region['class'] . '"]//div[@id="block-' . $block['module'] . '-' . $block['delta'] . '"]/*';
+ $xpath = $this->buildXPathQuery('//div[@class=:region-class]//div[@id=:block-id]/*', array(
+ ':region-class' => $region['class'],
+ ':block-id' => 'block-' . $block['module'] . '-' . $block['delta'],
+ ));
$this->assertFieldByXPath($xpath, FALSE, t('Custom block found in %region_name region.', array('%region_name' => $region['name'])));
}
}
diff --git a/modules/book/book.test b/modules/book/book.test
index d68a17ab3..9b216f38a 100644
--- a/modules/book/book.test
+++ b/modules/book/book.test
@@ -129,7 +129,7 @@ class BookTestCase extends DrupalWebTestCase {
}
// Fetch links in the current breadcrumb.
- $links = $this->xpath("//div[@class='breadcrumb']/a");
+ $links = $this->xpath('//div[@class="breadcrumb"]/a');
$got_breadcrumb = array();
foreach ($links as $link) {
$got_breadcrumb[] = (string) $link['href'];
diff --git a/modules/comment/comment.test b/modules/comment/comment.test
index f9d151ea7..ab81035ff 100644
--- a/modules/comment/comment.test
+++ b/modules/comment/comment.test
@@ -762,7 +762,7 @@ class CommentPagerTest extends CommentHelperCase {
$expected_cids[] = $comments[$key]->id;
}
- $comment_anchors = $this->xpath("//a[starts-with(@id,'comment-')]");
+ $comment_anchors = $this->xpath('//a[starts-with(@id,"comment-")]');
$result_order = array();
foreach ($comment_anchors as $anchor) {
$result_order[] = substr($anchor['id'], 8);
@@ -1134,13 +1134,13 @@ class CommentRdfaTestCase extends CommentHelperCase {
// Tests number of comments in teaser view.
$this->drupalGet('node');
- $comment_count_teaser = $this->xpath("//div[contains(@typeof, 'sioc:Item')]//li[contains(@class, 'comment_comments')]/a[contains(@property, 'sioc:num_replies') and contains(@content, '2') and @datatype='xsd:integer']");
+ $comment_count_teaser = $this->xpath('//div[contains(@typeof, "sioc:Item")]//li[contains(@class, "comment_comments")]/a[contains(@property, "sioc:num_replies") and contains(@content, "2") and @datatype="xsd:integer"]');
$this->assertTrue(!empty($comment_count_teaser), t('RDFa markup for the number of comments found on teaser view.'));
// Tests number of comments in full node view.
$this->drupalGet('node/' . $this->node1->nid);
$node_url = url('node/' . $this->node1->nid);
- $comment_count_teaser = $this->xpath("/html/head/meta[@about='$node_url' and @property='sioc:num_replies' and @content='2' and @datatype='xsd:integer']");
+ $comment_count_teaser = $this->xpath('/html/head/meta[@about=:node-url and @property="sioc:num_replies" and @content="2" and @datatype="xsd:integer"]', array(':node-url' => $node_url));
$this->assertTrue(!empty($comment_count_teaser), t('RDFa markup for the number of comments found on full node view.'));
}
@@ -1180,10 +1180,10 @@ class CommentRdfaTestCase extends CommentHelperCase {
// Tests comment #2 as anonymous user.
$this->_testBasicCommentRdfaMarkup($comment2, $anonymous_user);
// Tests the RDFa markup for the homepage (specific to anonymous comments).
- $comment_homepage = $this->xpath("//div[contains(@class, 'comment') and contains(@typeof, 'sioct:Comment')]//span[@rel='sioc:has_creator']/a[contains(@class, 'username') and @typeof='sioc:User' and @property='foaf:name' and @href='http://example.org/' and contains(@rel, 'foaf:page')]");
+ $comment_homepage = $this->xpath('//div[contains(@class, "comment") and contains(@typeof, "sioct:Comment")]//span[@rel="sioc:has_creator"]/a[contains(@class, "username") and @typeof="sioc:User" and @property="foaf:name" and @href="http://example.org/" and contains(@rel, "foaf:page")]');
$this->assertTrue(!empty($comment_homepage), t('RDFa markup for the homepage of anonymous user found.'));
// There should be no about attribute on anonymous comments.
- $comment_homepage = $this->xpath("//div[contains(@class, 'comment') and contains(@typeof, 'sioct:Comment')]//span[@rel='sioc:has_creator']/a[@about]");
+ $comment_homepage = $this->xpath('//div[contains(@class, "comment") and contains(@typeof, "sioct:Comment")]//span[@rel="sioc:has_creator"]/a[@about]');
$this->assertTrue(empty($comment_homepage), t('No about attribute is present on anonymous user comment.'));
// Tests comment #2 as logged in user.
@@ -1191,11 +1191,11 @@ class CommentRdfaTestCase extends CommentHelperCase {
$this->drupalGet('node/' . $this->node2->nid);
$this->_testBasicCommentRdfaMarkup($comment2, $anonymous_user);
// Tests the RDFa markup for the homepage (specific to anonymous comments).
- $comment_homepage = $this->xpath("//div[contains(@class, 'comment') and contains(@typeof, 'sioct:Comment')]//span[@rel='sioc:has_creator']/a[contains(@class, 'username') and @typeof='sioc:User' and @property='foaf:name' and @href='http://example.org/' and contains(@rel, 'foaf:page')]");
- $this->assertTrue(!empty($comment_homepage), t('RDFa markup for the homepage of anonymous user found.'));
+ $comment_homepage = $this->xpath('//div[contains(@class, "comment") and contains(@typeof, "sioct:Comment")]//span[@rel="sioc:has_creator"]/a[contains(@class, "username") and @typeof="sioc:User" and @property="foaf:name" and @href="http://example.org/" and contains(@rel, "foaf:page")]');
+ $this->assertTrue(!empty($comment_homepage), t("RDFa markup for the homepage of anonymous user found."));
// There should be no about attribute on anonymous comments.
- $comment_homepage = $this->xpath("//div[contains(@class, 'comment') and contains(@typeof, 'sioct:Comment')]//span[@rel='sioc:has_creator']/a[@about]");
- $this->assertTrue(empty($comment_homepage), t('No about attribute is present on anonymous user comment.'));
+ $comment_homepage = $this->xpath('//div[contains(@class, "comment") and contains(@typeof, "sioct:Comment")]//span[@rel="sioc:has_creator"]/a[@about]');
+ $this->assertTrue(empty($comment_homepage), t("No about attribute is present on anonymous user comment."));
}
/**
@@ -1209,18 +1209,18 @@ class CommentRdfaTestCase extends CommentHelperCase {
* An array containing information about an anonymous user.
*/
function _testBasicCommentRdfaMarkup($comment, $account = array()) {
- $comment_container = $this->xpath("//div[contains(@class, 'comment') and contains(@typeof, 'sioct:Comment')]");
- $this->assertTrue(!empty($comment_container), t('Comment RDF type for comment found.'));
- $comment_title = $this->xpath("//div[contains(@class, 'comment') and contains(@typeof, 'sioct:Comment')]//h3[@property='dc:title']");
- $this->assertEqual((string)$comment_title[0]->a, $comment->subject, t('RDFa markup for the comment title found.'));
- $comment_date = $this->xpath("//div[contains(@class, 'comment') and contains(@typeof, 'sioct:Comment')]//*[contains(@property, 'dc:date') and contains(@property, 'dc:created')]");
- $this->assertTrue(!empty($comment_date), t('RDFa markup for the date of the comment found.'));
+ $comment_container = $this->xpath('//div[contains(@class, "comment") and contains(@typeof, "sioct:Comment")]');
+ $this->assertTrue(!empty($comment_container), t("Comment RDF type for comment found."));
+ $comment_title = $this->xpath('//div[contains(@class, "comment") and contains(@typeof, "sioct:Comment")]//h3[@property="dc:title"]');
+ $this->assertEqual((string)$comment_title[0]->a, $comment->subject, t("RDFa markup for the comment title found."));
+ $comment_date = $this->xpath('//div[contains(@class, "comment") and contains(@typeof, "sioct:Comment")]//*[contains(@property, "dc:date") and contains(@property, "dc:created")]');
+ $this->assertTrue(!empty($comment_date), t("RDFa markup for the date of the comment found."));
// The author tag can be either a or span
- $comment_author = $this->xpath("//div[contains(@class, 'comment') and contains(@typeof, 'sioct:Comment')]//span[@rel='sioc:has_creator']/*[contains(@class, 'username') and @typeof='sioc:User' and @property='foaf:name']");
- $name = empty($account['name']) ? $this->web_user->name : $account['name'] . ' (not verified)';
- $this->assertEqual((string)$comment_author[0], $name, t('RDFa markup for the comment author found.'));
- $comment_body = $this->xpath("//div[contains(@class, 'comment') and contains(@typeof, 'sioct:Comment')]//div[@class='content']//div[contains(@class, 'comment-body')]//div[@property='content:encoded']");
- $this->assertEqual((string)$comment_body[0]->p, $comment->comment, t('RDFa markup for the comment body found.'));
+ $comment_author = $this->xpath('//div[contains(@class, "comment") and contains(@typeof, "sioct:Comment")]//span[@rel="sioc:has_creator"]/*[contains(@class, "username") and @typeof="sioc:User" and @property="foaf:name"]');
+ $name = empty($account["name"]) ? $this->web_user->name : $account["name"] . " (not verified)";
+ $this->assertEqual((string)$comment_author[0], $name, t("RDFa markup for the comment author found."));
+ $comment_body = $this->xpath('//div[contains(@class, "comment") and contains(@typeof, "sioct:Comment")]//div[@class="content"]//div[contains(@class, "comment-body")]//div[@property="content:encoded"]');
+ $this->assertEqual((string)$comment_body[0]->p, $comment->comment, t("RDFa markup for the comment body found."));
}
}
diff --git a/modules/field/modules/options/options.test b/modules/field/modules/options/options.test
index 2d441204a..6f3a4cd51 100644
--- a/modules/field/modules/options/options.test
+++ b/modules/field/modules/options/options.test
@@ -247,7 +247,7 @@ class OptionsWidgetsTestCase extends FieldTestCase {
$instance['required'] = TRUE;
field_update_instance($instance);
$this->drupalGet('test-entity/' . $entity->ftid .'/edit');
- $this->assertFalse($this->xpath('//select[@id="edit-card-1-' . $langcode . '"]//option[@value=""]'), t('A required select list does not have an empty key.'));
+ $this->assertFalse($this->xpath('//select[@id=:id]//option[@value=""]', array(':id' => 'edit-card-1-' . $langcode)), t('A required select list does not have an empty key.'));
// We do not have to test that a required select list with one option is
// auto-selected because the browser does it for us.
@@ -363,7 +363,7 @@ class OptionsWidgetsTestCase extends FieldTestCase {
$instance['required'] = TRUE;
field_update_instance($instance);
$this->drupalGet('test-entity/' . $entity->ftid .'/edit');
- $this->assertFalse($this->xpath('//select[@id="edit-card-2-' . $langcode . '"]//option[@value=""]'), t('A required select list does not have an empty key.'));
+ $this->assertFalse($this->xpath('//select[@id=:id]//option[@value=""]', array(':id' => 'edit-card-2-' . $langcode)), t('A required select list does not have an empty key.'));
// We do not have to test that a required select list with one option is
// auto-selected because the browser does it for us.
diff --git a/modules/filter/filter.test b/modules/filter/filter.test
index dd10d93ef..3c4a35ee3 100644
--- a/modules/filter/filter.test
+++ b/modules/filter/filter.test
@@ -238,7 +238,10 @@ class FilterAdminTestCase extends DrupalWebTestCase {
$result = db_query('SELECT * FROM {cache_filter}')->fetchObject();
$this->assertFalse($result, t('Cache cleared.'));
- $elements = $this->xpath('//select[@name="filters[' . $first_filter . '][weight]"]/following::select[@name="filters[' . $second_filter . '][weight]"]');
+ $elements = $this->xpath('//select[@name=:first]/following::select[@name=:second]', array(
+ ':first' => 'filters[' . $first_filter . '][weight]',
+ ':second' => 'filters[' . $second_filter . '][weight]',
+ ));
$this->assertTrue(!empty($elements), t('Order confirmed in admin interface.'));
// Reorder filters.
@@ -249,7 +252,10 @@ class FilterAdminTestCase extends DrupalWebTestCase {
$this->assertFieldByName('filters[' . $second_filter . '][weight]', 1, t('Order saved successfully.'));
$this->assertFieldByName('filters[' . $first_filter . '][weight]', 2, t('Order saved successfully.'));
- $elements = $this->xpath('//select[@name="filters[' . $second_filter . '][weight]"]/following::select[@name="filters[' . $first_filter . '][weight]"]');
+ $elements = $this->xpath('//select[@name=:first]/following::select[@name=:second]', array(
+ ':first' => 'filters[' . $second_filter . '][weight]',
+ ':second' => 'filters[' . $first_filter . '][weight]',
+ ));
$this->assertTrue(!empty($elements), t('Reorder confirmed in admin interface.'));
$result = db_query('SELECT * FROM {filter} WHERE format = :format ORDER BY weight ASC', array(':format' => $filtered));
diff --git a/modules/locale/locale.test b/modules/locale/locale.test
index fecaf1bc6..a2add4610 100644
--- a/modules/locale/locale.test
+++ b/modules/locale/locale.test
@@ -1151,7 +1151,7 @@ class LanguageSwitchingFunctionalTest extends DrupalWebTestCase {
$this->assertText(t('Languages'), t('Language switcher block found.'));
// Assert that only the current language is marked as active.
- list($language_switcher) = $this->xpath("//div[@id=\"block-locale-{$language_type}\"]/div[@class=\"content\"]");
+ list($language_switcher) = $this->xpath('//div[@id=:id]/div[@class="content"]', array(':id' => 'block-locale-' . $language_type));
$links = array(
'active' => array(),
'inactive' => array(),
@@ -1270,7 +1270,7 @@ class LocaleUserLanguageFunctionalTest extends DrupalWebTestCase {
// Ensure form was submitted successfully.
$this->assertText(t('The changes have been saved.'), t('Changes were saved.'));
// Check if language was changed.
- $elements = $this->xpath('//input[@id="edit-language-' . $langcode . '"]');
+ $elements = $this->xpath('//input[@id=:id]', array(':id' => 'edit-language-' . $langcode));
$this->assertTrue(isset($elements[0]) && !empty($elements[0]['checked']), t('Default language successfully updated.'));
$this->drupalLogout();
@@ -1886,17 +1886,18 @@ class LocaleMultilingualFieldsFunctionalTest extends DrupalWebTestCase {
// Check if node body is showed.
$this->drupalGet("node/$node->nid");
- $body_xpath = '//div[@id="node-' . $node->nid . '"]//div[@property="content:encoded"]/p';
- $this->assertEqual(current($this->xpath($body_xpath)), $node->body['en'][0]['value'], 'Node body is correctly showed.');
+ $body = $this->xpath('//div[@id=:id]//div[@property="content:encoded"]/p', array(':id' => 'node-' . $node->nid));
+ $this->assertEqual(current($body), $node->body['en'][0]['value'], 'Node body is correctly showed.');
$settings['body[full][type]'] = 'hidden';
$this->drupalPost('admin/structure/types/manage/page/display', $settings, t('Save'));
- $select_xpath = '//select[@id="edit-body-full-type"]/option[@selected="selected"]';
+ $select = $this->xpath('//select[@id="edit-body-full-type"]/option[@selected="selected"]');
// Check if body display is actually "hidden" for the "full" view mode.
- $this->assertEqual(current($this->xpath($select_xpath)), '<Hidden>', 'Body display is actually "hidden" for the "full" view mode');
+ $this->assertEqual(current($select), '<Hidden>', 'Body display is actually "hidden" for the "full" view mode');
$this->drupalGet("node/$node->nid");
// Check if node body is not showed.
- $this->assertFalse(is_array($this->xpath($body_xpath)), 'Body correctly not showed.');
+ $body = $this->xpath('//div[@id=:id]//div[@property="content:encoded"]/p', array(':id' => 'node-' . $node->nid));
+ $this->assertFalse(is_array($body), 'Body correctly not showed.');
}
}
diff --git a/modules/node/node.test b/modules/node/node.test
index b7ae58a91..a97501f3f 100644
--- a/modules/node/node.test
+++ b/modules/node/node.test
@@ -1247,8 +1247,7 @@ class NodeTitleTestCase extends DrupalWebTestCase {
$this->assertEqual(current($this->xpath($xpath)), $node->title, 'Node breadcrumb is equal to node title.', 'Node');
// Test node title in comment preview.
- $xpath = '//div[@id="node-'. $node->nid .'"]/h2/a';
- $this->assertEqual(current($this->xpath($xpath)), $node->title, 'Node preview title is equal to node title.', 'Node');
+ $this->assertEqual(current($this->xpath('//div[@id=:id]/h2/a', array(':id' => 'node-' . $node->nid))), $node->title, 'Node preview title is equal to node title.', 'Node');
}
}
diff --git a/modules/rdf/rdf.test b/modules/rdf/rdf.test
index 85dac8970..18545a186 100644
--- a/modules/rdf/rdf.test
+++ b/modules/rdf/rdf.test
@@ -165,9 +165,15 @@ class RdfMarkupTestCase extends DrupalWebTestCase {
// We only check to make sure that the resource attribute contains '.txt'
// instead of the full file name because the filename is altered on upload.
- $file_rel = $this->xpath("//div[contains(@about, 'node/$nid')]//div[contains(@rel, 'rdfs:seeAlso') and contains(@resource, '.txt')]");
+ $file_rel = $this->xpath('//div[contains(@about, :node-uri)]//div[contains(@rel, "rdfs:seeAlso") and contains(@resource, ".txt")]', array(
+ ':node-uri' => 'node/' . $nid,
+ ));
$this->assertTrue(!empty($file_rel), t('Attribute \'rel\' set on file field. Attribute \'resource\' is also set.'));
- $image_rel = $this->xpath("//div[contains(@about, 'node/$nid')]//div[contains(@rel, 'rdfs:seeAlso') and contains(@resource, '$image_filename')]//img[contains(@typeof, 'foaf:Image')]");
+ $image_rel = $this->xpath('//div[contains(@about, :node-uri)]//div[contains(@rel, "rdfs:seeAlso") and contains(@resource, :image)]//img[contains(@typeof, "foaf:Image")]', array(
+ ':node-uri' => 'node/' . $nid,
+ ':image' => $image_filename,
+ ));
+
$this->assertTrue(!empty($image_rel), t('Attribute \'rel\' set on image field. Attribute \'resource\' is also set.'));
}
}
@@ -315,11 +321,22 @@ class RdfMappingDefinitionTestCase extends DrupalWebTestCase {
// page. These attributes come from the user default bundle definition.
$account_uri = url('user/' . $user2->uid);
$person_uri = url('user/' . $user2->uid, array('fragment' => 'me'));
- $user2_profile_about = $this->xpath("//div[@class='profile' and @typeof='sioc:User' and @about='$account_uri']");
+
+ $user2_profile_about = $this->xpath('//div[@class="profile" and @typeof="sioc:User" and @about=:account-uri]', array(
+ ':account-uri' => $account_uri,
+ ));
$this->assertTrue(!empty($user2_profile_about), t('RDFa markup found on user profile page'));
- $user_account_holder = $this->xpath("//meta[contains(@typeof, 'foaf:Person') and @about='$person_uri' and @resource='$account_uri' and contains(@rel, 'foaf:account')]");
+
+ $user_account_holder = $this->xpath('//meta[contains(@typeof, "foaf:Person") and @about=:person-uri and @resource=:account-uri and contains(@rel, "foaf:account")]', array(
+ ':person-uri' => $person_uri,
+ ':account-uri' => $account_uri,
+ ));
$this->assertTrue(!empty($user_account_holder), t('URI created for account holder and username set on sioc:User.'));
- $user_username = $this->xpath("//meta[@about='$account_uri' and contains(@property, 'foaf:name') and @content='$username']");
+
+ $user_username = $this->xpath('//meta[@about=:account-uri and contains(@property, "foaf:name") and @content=:username]', array(
+ ':account-uri' => $account_uri,
+ ':username' => $username,
+ ));
$this->assertTrue(!empty($user_username), t('foaf:name set on username.'));
// User 2 creates node.
@@ -329,7 +346,9 @@ class RdfMappingDefinitionTestCase extends DrupalWebTestCase {
$this->drupalGet('node/' . $node->nid);
// Ensures the default bundle mapping for user is used on the Authored By
// information on the node.
- $author_about = $this->xpath("//a[@typeof='sioc:User' and @about='$account_uri' and @property='foaf:name' and contains(@xml:lang, '')]");
+ $author_about = $this->xpath('//a[@typeof="sioc:User" and @about=:account-uri and @property="foaf:name" and contains(@xml:lang, "")]', array(
+ ':account-uri' => $account_uri,
+ ));
$this->assertTrue(!empty($author_about), t('RDFa markup found on author information on post. xml:lang on username is set to empty string.'));
}
@@ -344,7 +363,10 @@ class RdfMappingDefinitionTestCase extends DrupalWebTestCase {
$this->drupalGet('taxonomy/term/' . $term->tid);
$term_url = url('taxonomy/term/' . $term->tid);
$term_name = $term->name;
- $term_rdfa_meta = $this->xpath("//meta[@typeof='skos:Concept' and @about='$term_url' and contains(@property, 'rdfs:label') and contains(@property, 'skos:prefLabel') and @content='$term_name']");
+ $term_rdfa_meta = $this->xpath('//meta[@typeof="skos:Concept" and @about=:term-url and contains(@property, "rdfs:label") and contains(@property, "skos:prefLabel") and @content=:term-name]', array(
+ ':term-url' => $term_url,
+ ':term-name' => $term_name,
+ ));
$this->assertTrue(!empty($term_rdfa_meta), t('RDFa markup found on term page.'));
}
}
@@ -406,19 +428,19 @@ class RdfTrackerAttributesTestCase extends DrupalWebTestCase {
// Tests whether the about property is applied. This is implicit in the
// success of the following tests, but making it explicit will make
// debugging easier in case of failure.
- $tracker_about = $this->xpath("//tr[@about='$url']");
+ $tracker_about = $this->xpath('//tr[@about=:url]', array(':url' => $url));
$this->assertTrue(!empty($tracker_about), t('About attribute found on table row for @user content.', array('@user'=> $user)));
// Tests whether the title has the correct property attribute.
- $tracker_title = $this->xpath("//tr[@about='$url']/td[@property='dc:title' and @datatype='']");
+ $tracker_title = $this->xpath('//tr[@about=:url]/td[@property="dc:title" and @datatype=""]', array(':url' => $url));
$this->assertTrue(!empty($tracker_title), t('Title property attribute found on @user content.', array('@user'=> $user)));
// Tests whether the relationship between the content and user has been set.
- $tracker_user = $this->xpath("//tr[@about='$url']//td[contains(@rel, 'sioc:has_creator')]//*[contains(@typeof, 'sioc:User') and contains(@property, 'foaf:name')]");
+ $tracker_user = $this->xpath('//tr[@about=:url]//td[contains(@rel, "sioc:has_creator")]//*[contains(@typeof, "sioc:User") and contains(@property, "foaf:name")]', array(':url' => $url));
$this->assertTrue(!empty($tracker_user), t('Typeof and name property attributes found on @user.', array('@user'=> $user)));
// There should be an about attribute on logged in users and no about
// attribute for anonymous users.
- $tracker_user = $this->xpath("//tr[@about='$url']//td[@rel='sioc:has_creator']/*[@about]");
+ $tracker_user = $this->xpath('//tr[@about=:url]//td[@rel="sioc:has_creator"]/*[@about]', array(':url' => $url));
if ($node->uid == 0) {
$this->assertTrue(empty($tracker_user), t('No about attribute is present on @user.', array('@user'=> $user)));
}
@@ -427,14 +449,14 @@ class RdfTrackerAttributesTestCase extends DrupalWebTestCase {
}
// Tests whether the property has been set for number of comments.
- $tracker_replies = $this->xpath("//tr[@about='$url']//td[contains(@property, 'sioc:num_replies') and contains(@content, '0') and @datatype='xsd:integer']");
+ $tracker_replies = $this->xpath('//tr[@about=:url]//td[contains(@property, "sioc:num_replies") and contains(@content, "0") and @datatype="xsd:integer"]', array(':url' => $url));
$this->assertTrue($tracker_replies, t('Num replies property and content attributes found on @user content.', array('@user'=> $user)));
// Tests that the appropriate RDFa markup to annotate the latest activity
// date has been added to the tracker output before comments have been
// posted, meaning the latest activity reflects changes to the node itself.
$isoDate = date('c', $node->changed);
- $tracker_activity = $this->xpath("//tr[@about='$url']//td[contains(@property, 'dc:modified') and contains(@property, 'sioc:last_activity_date') and contains(@datatype, 'xsd:dateTime') and @content='$isoDate']");
+ $tracker_activity = $this->xpath('//tr[@about=:url]//td[contains(@property, "dc:modified") and contains(@property, "sioc:last_activity_date") and contains(@datatype, "xsd:dateTime") and @content=:date]', array(':url' => $url, ':date' => $isoDate));
$this->assertTrue(!empty($tracker_activity), t('Latest activity date and changed properties found when there are no comments on @user content. Latest activity date content is correct.', array('@user'=> $user)));
// Tests that the appropriate RDFa markup to annotate the latest activity
@@ -443,7 +465,7 @@ class RdfTrackerAttributesTestCase extends DrupalWebTestCase {
$this->drupalGet('tracker');
// Tests whether the property has been set for number of comments.
- $tracker_replies = $this->xpath("//tr[@about='$url']//td[contains(@property, 'sioc:num_replies') and contains(@content, '1') and @datatype='xsd:integer']");
+ $tracker_replies = $this->xpath('//tr[@about=:url]//td[contains(@property, "sioc:num_replies") and contains(@content, "1") and @datatype="xsd:integer"]', array(':url' => $url));
$this->assertTrue($tracker_replies, t('Num replies property and content attributes found on @user content.', array('@user'=> $user)));
// Need to query database directly to obtain last_activity_date because
@@ -453,7 +475,7 @@ class RdfTrackerAttributesTestCase extends DrupalWebTestCase {
$expected_last_activity_date = $node->changed;
}
$isoDate = date('c', $expected_last_activity_date);
- $tracker_activity = $this->xpath("//tr[@about='$url']//td[@property='sioc:last_activity_date' and @datatype='xsd:dateTime' and @content='$isoDate']");
+ $tracker_activity = $this->xpath('//tr[@about=:url]//td[@property="sioc:last_activity_date" and @datatype="xsd:dateTime" and @content=:date]', array(':url' => $url, ':date' => $isoDate));
$this->assertTrue(!empty($tracker_activity), t('Latest activity date found when there are comments on @user content. Latest activity date content is correct.', array('@user'=> $user)));
}
}
diff --git a/modules/simpletest/drupal_web_test_case.php b/modules/simpletest/drupal_web_test_case.php
index 81270b2f9..5d64abb5c 100644
--- a/modules/simpletest/drupal_web_test_case.php
+++ b/modules/simpletest/drupal_web_test_case.php
@@ -1900,6 +1900,48 @@ class DrupalWebTestCase extends DrupalTestCase {
}
/**
+ * Builds an XPath query.
+ *
+ * Builds an XPath query by replacing placeholders in the query by the value
+ * of the arguments.
+ *
+ * XPath 1.0 (the version supported by libxml2, the underlying XML library
+ * used by PHP) doesn't support any form of quotation. This function
+ * simplifies the building of XPath expression.
+ *
+ * @param $xpath
+ * An XPath query, possibly with placeholders in the form ':name'.
+ * @param $args
+ * An array of arguments with keys in the form ':name' matching the
+ * placeholders in the query. The values may be either strings or numeric
+ * values.
+ * @return
+ * An XPath query with arguments replaced.
+ */
+ protected function buildXPathQuery($xpath, array $args = array()) {
+ // Replace placeholders.
+ foreach ($args as $placeholder => $value) {
+ // XPath 1.0 doesn't support a way to escape single or double quotes in a
+ // string literal. We split double quotes out of the string, and encode
+ // them separately.
+ if (is_string($value)) {
+ // Explode the text at the quote characters.
+ $parts = explode('"', $value);
+
+ // Quote the parts.
+ foreach ($parts as &$part) {
+ $part = '"' . $part . '"';
+ }
+
+ // Return the string.
+ $value = count($parts) > 1 ? 'concat(' . implode(', \'"\', ', $parts) . ')' : $parts[0];
+ }
+ $xpath = preg_replace('/' . preg_quote($placeholder) . '\b/', $value, $xpath);
+ }
+ return $xpath;
+ }
+
+ /**
* Perform an xpath search on the contents of the internal browser. The search
* is relative to the root element (HTML tag normally) of the page.
*
@@ -1910,11 +1952,14 @@ class DrupalWebTestCase extends DrupalTestCase {
* format and return values see the SimpleXML documentation,
* http://us.php.net/manual/function.simplexml-element-xpath.php.
*/
- protected function xpath($xpath) {
+ protected function xpath($xpath, array $arguments = array()) {
if ($this->parse()) {
+ $xpath = $this->buildXPathQuery($xpath, $arguments);
return $this->elements->xpath($xpath);
}
- return FALSE;
+ else {
+ return FALSE;
+ }
}
/**
@@ -1957,7 +2002,7 @@ class DrupalWebTestCase extends DrupalTestCase {
* TRUE if the assertion succeeded, FALSE otherwise.
*/
protected function assertLink($label, $index = 0, $message = '', $group = 'Other') {
- $links = $this->xpath('//a[text()="' . $label . '"]');
+ $links = $this->xpath('//a[text()=:label]', array(':label' => $label));
$message = ($message ? $message : t('Link with label %label found.', array('%label' => $label)));
return $this->assert(isset($links[$index]), $message, $group);
}
@@ -1977,7 +2022,7 @@ class DrupalWebTestCase extends DrupalTestCase {
* TRUE if the assertion succeeded, FALSE otherwise.
*/
protected function assertNoLink($label, $message = '', $group = 'Other') {
- $links = $this->xpath('//a[text()="' . $label . '"]');
+ $links = $this->xpath('//a[text()=:label]', array(':label' => $label));
$message = ($message ? $message : t('Link with label %label not found.', array('%label' => $label)));
return $this->assert(empty($links), $message, $group);
}
@@ -1998,7 +2043,7 @@ class DrupalWebTestCase extends DrupalTestCase {
* TRUE if the assertion succeeded, FALSE otherwise.
*/
protected function assertLinkByHref($href, $index = 0, $message = '', $group = 'Other') {
- $links = $this->xpath('//a[contains(@href, "' . $href . '")]');
+ $links = $this->xpath('//a[contains(@href, :href)]', array(':href' => $href));
$message = ($message ? $message : t('Link containing href %href found.', array('%href' => $href)));
return $this->assert(isset($links[$index]), $message, $group);
}
@@ -2017,7 +2062,7 @@ class DrupalWebTestCase extends DrupalTestCase {
* TRUE if the assertion succeeded, FALSE otherwise.
*/
protected function assertNoLinkByHref($href, $message = '', $group = 'Other') {
- $links = $this->xpath('//a[contains(@href, "' . $href . '")]');
+ $links = $this->xpath('//a[contains(@href, :href)]', array(':href' => $href));
$message = ($message ? $message : t('No link containing href %href found.', array('%href' => $href)));
return $this->assert(empty($links), $message, $group);
}
@@ -2039,7 +2084,7 @@ class DrupalWebTestCase extends DrupalTestCase {
*/
protected function clickLink($label, $index = 0) {
$url_before = $this->getUrl();
- $urls = $this->xpath('//a[text()="' . $label . '"]');
+ $urls = $this->xpath('//a[text()=:label]', array(':label' => $label));
if (isset($urls[$index])) {
$url_target = $this->getAbsoluteUrl($urls[$index]['href']);
@@ -2657,7 +2702,7 @@ class DrupalWebTestCase extends DrupalTestCase {
* TRUE on pass, FALSE on fail.
*/
protected function assertFieldChecked($id, $message = '') {
- $elements = $this->xpath('//input[@id="' . $id . '"]');
+ $elements = $this->xpath('//input[@id=:id]', array(':id' => $id));
return $this->assertTrue(isset($elements[0]) && !empty($elements[0]['checked']), $message ? $message : t('Checkbox field @id is checked.', array('@id' => $id)), t('Browser'));
}
@@ -2672,7 +2717,7 @@ class DrupalWebTestCase extends DrupalTestCase {
* TRUE on pass, FALSE on fail.
*/
protected function assertNoFieldChecked($id, $message = '') {
- $elements = $this->xpath('//input[@id="' . $id . '"]');
+ $elements = $this->xpath('//input[@id=:id]', array(':id' => $id));
return $this->assertTrue(isset($elements[0]) && empty($elements[0]['checked']), $message ? $message : t('Checkbox field @id is not checked.', array('@id' => $id)), t('Browser'));
}
@@ -2689,7 +2734,7 @@ class DrupalWebTestCase extends DrupalTestCase {
* TRUE on pass, FALSE on fail.
*/
protected function assertOptionSelected($id, $option, $message = '') {
- $elements = $this->xpath('//select[@id="' . $id . '"]//option[@value="' . $option . '"]');
+ $elements = $this->xpath('//select[@id=:id]//option[@value=:option]', array(':id' => $id, ':option' => $option));
return $this->assertTrue(isset($elements[0]) && !empty($elements[0]['selected']), $message ? $message : t('Option @option for field @id is selected.', array('@option' => $option, '@id' => $id)), t('Browser'));
}
@@ -2706,7 +2751,7 @@ class DrupalWebTestCase extends DrupalTestCase {
* TRUE on pass, FALSE on fail.
*/
protected function assertNoOptionSelected($id, $option, $message = '') {
- $elements = $this->xpath('//select[@id="' . $id . '"]//option[@value="' . $option . '"]');
+ $elements = $this->xpath('//select[@id=:id]//option[@value=:option]', array(':id' => $id, ':option' => $option));
return $this->assertTrue(isset($elements[0]) && empty($elements[0]['selected']), $message ? $message : t('Option @option for field @id is not selected.', array('@option' => $option, '@id' => $id)), t('Browser'));
}
@@ -2753,7 +2798,8 @@ class DrupalWebTestCase extends DrupalTestCase {
* XPath for specified values.
*/
protected function constructFieldXpath($attribute, $value) {
- return '//textarea[@' . $attribute . '="' . $value . '"]|//input[@' . $attribute . '="' . $value . '"]|//select[@' . $attribute . '="' . $value . '"]';
+ $xpath = '//textarea[@' . $attribute . '=:value]|//input[@' . $attribute . '=:value]|//select[@' . $attribute . '=:value]';
+ return $this->buildXPathQuery($xpath, array(':value' => $value));
}
/**
diff --git a/modules/simpletest/simpletest.test b/modules/simpletest/simpletest.test
index 375dab881..11bf16ef7 100644
--- a/modules/simpletest/simpletest.test
+++ b/modules/simpletest/simpletest.test
@@ -281,13 +281,13 @@ class SimpleTestFunctionalTest extends DrupalWebTestCase {
}
/**
- * Test internal testing framework URL handling.
+ * Test internal testing framework browser.
*/
-class SimpleTestURLTestCase extends DrupalWebTestCase {
+class SimpleTestBrowserTestCase extends DrupalWebTestCase {
public static function getInfo() {
return array(
- 'name' => 'SimpleTest URL handling',
- 'description' => 'Test the URL handling in the testing framework.',
+ 'name' => 'SimpleTest browser',
+ 'description' => 'Test the internal browser of the testing framework.',
'group' => 'SimpleTest',
);
}
@@ -315,6 +315,28 @@ class SimpleTestURLTestCase extends DrupalWebTestCase {
$this->assertEqual($absolute, $this->url, t('Passed and requested URL are equal.'));
$this->assertEqual($this->url, $this->getAbsoluteUrl($this->url), t('Requested and returned absolute URL are equal.'));
}
+
+ /**
+ * Tests XPath escaping.
+ */
+ function testXPathEscaping() {
+ $testpage = <<< EOF
+<html>
+<body>
+<a href="link1">A "weird" link, just to bother the dumb "XPath 1.0"</a>
+<a href="link2">A second "even more weird" link, in memory of George O'Malley</a>
+</body>
+</html>
+EOF;
+ $this->drupalSetContent($testpage);
+
+ // Matches the first link.
+ $urls = $this->xpath('//a[text()=:text]', array(':text' => 'A "weird" link, just to bother the dumb "XPath 1.0"'));
+ $this->assertEqual($urls[0]['href'], 'link1', 'Match with quotes.');
+
+ $urls = $this->xpath('//a[text()=:text]', array(':text' => 'A second "even more weird" link, in memory of George O\'Malley'));
+ $this->assertEqual($urls[0]['href'], 'link2', 'Match with mixed single and double quotes.');
+ }
}
class SimpleTestMailCaptureTestCase extends DrupalWebTestCase {
diff --git a/modules/syslog/syslog.test b/modules/syslog/syslog.test
index 6a0dbafd0..4f0950dd9 100644
--- a/modules/syslog/syslog.test
+++ b/modules/syslog/syslog.test
@@ -29,7 +29,7 @@ class SyslogTestCase extends DrupalWebTestCase {
$this->drupalGet('admin/config/development/logging');
if ($this->parse()) {
- $field = $this->xpath('//option[@value="' . LOG_LOCAL6 . '"]'); // Should be one field.
+ $field = $this->xpath('//option[@value=:value]', array(':value' => LOG_LOCAL6)); // Should be one field.
$this->assertTrue($field[0]['selected'] == 'selected', t('Facility value saved.'));
}
}
diff --git a/modules/translation/translation.test b/modules/translation/translation.test
index 0ef64c275..19b421df8 100644
--- a/modules/translation/translation.test
+++ b/modules/translation/translation.test
@@ -110,7 +110,7 @@ class TranslationTestCase extends DrupalWebTestCase {
$this->assertRaw(t('The language %language has been created and can now be used. More information is available on the <a href="@locale-help">help screen</a>.', array('%language' => $languages[$language_code]->name, '@locale-help' => url('admin/help/locale'))), t('Language has been created.'));
}
}
- elseif ($this->xpath('//input[@type=\'checkbox\' and @name=\'enabled[' . $language_code . ']\' and @checked=\'checked\']')) {
+ elseif ($this->xpath('//input[@type="checkbox" and @name=:name and @checked="checked"]', array(':name' => 'enabled[' . $language_code . ']'))) {
// It's installed and enabled. No need to do anything.
$this->assertTrue(true, 'Language [' . $language_code . '] already installed and enabled.');
}