Commit 6fc055ab authored by Dries's avatar Dries

- Patch #730220 by Berdir, aspilicious, Damien Tournoud, pwolanin: improved xpath tests.

parent e0871ec4
......@@ -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'])));
}
}
......
......@@ -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'];
......
......@@ -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."));
}
}
......
......@@ -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.
......
......@@ -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));
......
......@@ -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.');
}
}
......
......@@ -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');
}
}
......
......@@ -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)));
}
}
......@@ -1899,6 +1899,48 @@ protected function handleForm(&$post, &$edit, &$upload, $submit, $form) {
return $submit_matches;
}
/**
* 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 @@ protected function handleForm(&$post, &$edit, &$upload, $submit, $form) {
* 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 @@ protected function getAllOptions(SimpleXMLElement $element) {
* 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 @@ protected function assertLink($label, $index = 0, $message = '', $group = 'Other
* 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 @@ protected function assertNoLink($label, $message = '', $group = 'Other') {
* 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 @@ protected function assertLinkByHref($href, $index = 0, $message = '', $group = '
* 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 @@ protected function assertNoLinkByHref($href, $message = '', $group = 'Other') {
*/
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 @@ protected function assertNoFieldById($id, $value = '', $message = '') {
* 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 @@ protected function assertFieldChecked($id, $message = '') {
* 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 @@ protected function assertNoFieldChecked($id, $message = '') {
* 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 @@ protected function assertOptionSelected($id, $option, $message = '') {
* 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 @@ protected function assertNoField($field, $message = '', $group = 'Other') {
* 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));
}
/**
......
......@@ -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 {
......
......@@ -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.'));
}
}
......
......@@ -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.');
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment