Skip to content

Commit

Permalink
fix xpath locator
Browse files Browse the repository at this point in the history
  • Loading branch information
Lukas Mestan committed Aug 18, 2017
1 parent efc0a0e commit ad35f31
Show file tree
Hide file tree
Showing 7 changed files with 156 additions and 75 deletions.
200 changes: 127 additions & 73 deletions src/HighlightCeption.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@
use Codeception\Module;
use Codeception\TestInterface;
use Codeception\Exception\ConfigurationException;
use Codeception\Util\Locator;

class HighlightCeption extends Module
{

/**
* Configuration array
*
Expand All @@ -21,84 +23,31 @@ class HighlightCeption extends Module
'timeWait' => 1,
'module' => 'WebDriver'
];

/**
* Css style for hightlight text or element
*
* @var array
*/
private $cssStyle = [];

/**
* Time wait
*
* @var float|integer
*/
private $timeWait = 0;

/**
* @var RemoteWebDriver
*/
private $webDriver = null;

/**
* @var WebDriver
*/
private $webDriverModule = null;


/**
* Highlight text on site
*
* @param string $text
*/
private function highlightText($text)
{
$this->webDriverModule->executeJs('jQuery.fn.highlight=function(c){function e(b,c){var d=0;if(3==b.nodeType){var a=b.data.toUpperCase().indexOf(c),a=a-(b.data.substr(0,a).toUpperCase().length-b.data.substr(0,a).length);if(0<=a){d=document.createElement("span");d.className="highlight";a=b.splitText(a);a.splitText(c.length);var f=a.cloneNode(!0);d.appendChild(f);a.parentNode.replaceChild(d,a);d=1}}else if(1==b.nodeType&&b.childNodes&&!/(script|style)/i.test(b.tagName))for(a=0;a<b.childNodes.length;++a)a+=e(b.childNodes[a],c);return d} return this.length&&c&&c.length?this.each(function(){e(this,c.toUpperCase())}):this};jQuery.fn.removeHighlight=function(){return this.find("span.highlight").each(function(){this.parentNode.firstChild.nodeName;with(this.parentNode)replaceChild(this.firstChild,this),normalize()}).end()};');
$this->webDriverModule->executeJs('$("body").highlight("'.$text.'");');
$this->webDriverModule->executeJs(sprintf('$(".highlight").css(%s);', $this->cssStyle));
$this->webDriverModule->wait($this->timeWait);
}

/**
* Highlight element on site
*
* @param string|array $selector
*/
private function highlightElement($selector)
{
$cssSelector = $this->resolveCssSelector($selector);
if($cssSelector) {
$this->debug('[CSS Selector] '.$cssSelector);
$this->webDriverModule->executeJs(sprintf('$("%s").css(%s);', $cssSelector, $this->cssStyle));
$this->webDriverModule->wait($this->timeWait);
}
}

/**
* Resolve CSS selector
*
* @param string|array $selector
* @return boolean
*/
private function resolveCssSelector($selector)
{
if(isset($selector['css'])) {
return $selector['css'];
}

if(isset($selector['class'])) {
return '.'.$selector['class'];
}

if(isset($selector['id'])) {
return '#'.$selector['id'];
}

if(!empty($selector) && is_string($selector)) {
return $selector;
}

return false;
}

/**
* Event hook before a test starts
*
Expand All @@ -110,21 +59,26 @@ public function _before(TestInterface $test)
if (!$this->hasModule($this->config['module'])) {
throw new ConfigurationException("HighlightCeption uses the WebDriver. Please ensure that this module is activated.");
}

$this->webDriverModule = $this->getModule($this->config['module']);
$this->webDriver = $this->webDriverModule->webDriver;

if ($this->webDriver->executeScript('return !window.jQuery;')) {
$jQueryString = file_get_contents(__DIR__ . "/jquery.js");
$this->webDriver->executeScript($jQueryString);
$this->webDriver->executeScript('jQuery.noConflict();');
}

$this->timeWait = floatval($this->config['timeWait']);
$this->cssStyle = json_encode($this->config['cssStyle']);
$this->test = $test;
}

/**
* Event hook after a test starts
*
* @param TestInterface $test
* @throws ConfigurationException
*/
public function _after(TestInterface $test)
{
$this->webDriverModule->wait($this->timeWait);
$this->test = $test;
}

/**
* @inheritdoc
*/
Expand All @@ -133,16 +87,16 @@ public function see($text, $selector = null)
$this->highlightText($text);
$this->webDriverModule->see($text, $selector);
}

/**
* @inheritdoc
*/
public function seeElement($selector, $attributes = null)
public function seeElement($selector, $attributes = [])
{
$this->highlightElement($selector);
$this->webDriverModule->seeElement($selector, $attributes);
}

/**
* @inheritdoc
*/
Expand All @@ -151,7 +105,7 @@ public function seeLink($text, $url = null)
$this->highlightText($text);
$this->webDriverModule->seeLink($text, $url);
}

/**
* @inheritdoc
*/
Expand All @@ -168,7 +122,6 @@ public function click($link, $context = null)
{
$this->highlightElement($context);
$this->webDriverModule->click($link, $context);
$this->webDriverModule->wait($this->timeWait);
}

/**
Expand All @@ -178,7 +131,6 @@ public function clickWithLeftButton($cssOfXPath = null, $offsetX = null, $offset
{
$this->highlightElement($cssOfXPath);
$this->webDriverModule->clickWithLeftButton($cssOfXPath, $offsetX, $offsetY);
$this->webDriverModule->wait($this->timeWait);
}

/**
Expand All @@ -188,7 +140,109 @@ public function clickWithRightButton($cssOfXPath = null, $offsetX = null, $offse
{
$this->highlightElement($cssOfXPath);
$this->webDriverModule->clickWithRightButton($cssOfXPath, $offsetX, $offsetY);
$this->webDriverModule->wait($this->timeWait);
}

}
/**
* Highlight text on site
*
* @param string $text
*/
private function highlightText($text)
{
$this->loadJQuery();
$this->debug('[Highlight Text] ' . $text);
$this->webDriverModule->executeJs('jQuery(document).ready(function (){
jQuery("body").highlight("' . $text . '");
' . sprintf('jQuery(".highlight").css(%s);', $this->cssStyle) . '
});');
}

/**
* Highlight element on site
*
* @param string|array $selector
*/
private function highlightElement($selector)
{
$locator = $this->getSelector($selector);
if ($locator) {
$this->loadJQuery();
if (Locator::isXPath($locator)) {
$this->loadJQueryXPath();
$this->debug('[Highlight XPath] ' . Locator::humanReadableString($locator));
$this->webDriverModule->executeJs(sprintf('jQuery(document).xpath("%s").css(%s);', addslashes($locator), $this->cssStyle));
} else {
$this->debug('[Highlight Selector] ' . Locator::humanReadableString($locator));
$this->webDriverModule->executeJs(sprintf('jQuery("%s").css(%s);', addslashes($locator), $this->cssStyle));
}
}
}

/**
* Resolve selector
*
* @param string|array $selector
* @return boolean
* @todo
*/
private function getSelector($selector)
{
if (isset($selector['css'])) {
return $selector['css'];
}

if (isset($selector['class'])) {
return '.' . $selector['class'];
}

if (isset($selector['id'])) {
return '#' . $selector['id'];
}

if (isset($selector['xpath'])) {
return $selector['xpath'];
}

if (!empty($selector) && is_string($selector)) {
return $selector;
}

return false;
}

/**
* Load jQuery
*/
private function loadJQuery()
{
if ($this->webDriver->executeScript('return !window.jQuery;')) {
$jQueryString = file_get_contents(__DIR__ . "/jquery.min.js");
$this->webDriver->executeScript($jQueryString);
$this->webDriver->executeScript('jQuery.noConflict();');
$this->loadJQueryHighlight();
}
}

/**
* Load jQuery.XPath
*/
private function loadJQueryXPath()
{
if ($this->webDriver->executeScript('return !window.jQuery.fn.xpath;')) {
$jQueryXPath = file_get_contents(__DIR__ . "/jquery.xpath.min.js");
$this->webDriver->executeScript($jQueryXPath);
}
}

/**
* Load jQuery.Highlight
*/
private function loadJQueryHighlight()
{
if ($this->webDriver->executeScript('return !window.jQuery.fn.highlight;')) {
$jQueryString = file_get_contents(__DIR__ . "/jquery.highlight.min.js");
$this->webDriver->executeScript($jQueryString);
}
}

}
1 change: 1 addition & 0 deletions src/jquery.highlight.min.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

File renamed without changes.
13 changes: 13 additions & 0 deletions src/jquery.xpath.min.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion test/integration/tests/acceptance.suite.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ class_name: WebGuy
modules:
enabled:
- WebDriver:
url: http://www.hyperia.sk
url: https://news.ycombinator.com/
browser: phantomjs
#browser: chrome
host: localhost
Expand Down
5 changes: 4 additions & 1 deletion test/integration/tests/acceptance/SimpleCept.php
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
<?php
$I = new WebGuy($scenario);
$I->am('visitor');
$I->wantTo('check highlight text');
$I->amOnPage("/");
$I->see("Výkonnostný Marketing");
$I->see("comments");
$I->see("show");
$I->seeElement('.hnname');
10 changes: 10 additions & 0 deletions test/integration/tests/acceptance/XPathCept.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?php
$I = new WebGuy($scenario);
$I->am('visitor');
$I->wantTo('check highlight text');
$I->amOnPage('/login?goto=news');
$I->seeElement(['xpath' => "//input[@type='submit']"]);
$I->seeElement('//form//input[@type="text"]');
$I->seeElement("//a[contains(text(), 'Forgot')]");
$I->dontSeeElement(['name' => "Foo bar"]);
$I->dontSeeElement(['link' => "Click here"]);

0 comments on commit ad35f31

Please sign in to comment.