2016-06-29 3 views
2

У меня есть этот HTML-файл, test_xpath.htm:casperjs/slimerjs неверный селектор в waitForSelector, который работает в getElementByXPath?

<html> 
<head> 
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> 
</head> 

<body> 
    <h1>Hello World!</h1> 
    <div> 
    <a href="http://stackoverflow.com">Click me!</a> 
    </div> 
</body> 
</html> 

В папке этого файла, я запускаю PHP CLI> 5.4 в качестве сервера, как это:

php -S localhost:8080 

... поэтому страницу HTML имеется по адресу http://localhost:8080/test_xpath.htm.

Затем я запускаю этот код: SlimerJS

// run with: 
// SLIMERJSLAUNCHER=/usr/bin/firefox46 /home/USERNAME/.nvm/versions/node/v4.0.0/lib/node_modules/casperjs/bin/casperjs --engine=slimerjs test_xpath.js 

var casper = require('casper').create({ 
    verbose: true, 
    logLevel: 'debug', 
    userAgent: 'Mozilla/5.0 (X11; Linux i686; rv:43.0) Gecko/20100101 Firefox/43.0', 
    viewportSize: {width: 1024, height: 768}, 
    pageSettings: { 
    loadImages: false,//The script is much faster when this field is set to false 
    loadPlugins: false, 
    } 
}); 

casper.on("url.changed", function(){ 
    this.then(function(){ 
    this.echo("URL changed " + this.getCurrentUrl()); //getTitle()); 
    }); 
}); 

casper.on('remote.message', function(message) { 
    this.echo('remote message caught: ' + message); 
}); 

casper.start().thenOpen("http://localhost:8080/test_xpath.htm", function() { 
    console.log("website opened"); 
}); 

// set this to true to run - causes "[error] [remote] findAll(): invalid selector provided "//*[text()="Click me!"]":SyntaxError: An invalid or illegal string was specified" 
if (false) { 
    casper.waitForSelector('//*[text()="Click me!"]', function() { 
    this.echo("I'm sure //*[text()='Click me!'] is available in the DOM"); 
    }); 
} 

casper.then(function(){ 
    this.evaluate(function(){ 
    var aelem = __utils__.getElementByXPath('//*[text()="Click me!"]'); 
    aelem.click(); 
    }); 
}); 


casper.then(function(){ 
    casper.capture('TestCapture.png'); 
}); 

casper.run(); 

Если я запускаю код JS, как это - то есть, waitForSelector часть отключена if(false) - то все работает нормально.

Однако если включить эту часть, изменив if(false) к if(true), я получаю это:

$ SLIMERJSLAUNCHER=/usr/bin/firefox46 /home/USERNAME/.nvm/versions/node/v4.0.0/lib/node_modules/casperjs/bin/casperjs --engine=slimerjs test_xpath.js 
[info] [phantom] Starting... 
[info] [phantom] Running suite: 5 steps 
[debug] [phantom] opening url: http://localhost:8080/test_xpath.htm, HTTP GET 
[debug] [phantom] Navigation requested: url=http://localhost:8080/test_xpath.htm, type=Undefined, willNavigate=true, isMainFrame=true 
[debug] [phantom] url changed to "http://localhost:8080/test_xpath.htm" 
[debug] [phantom] Successfully injected Casper client-side utilities 
[info] [phantom] Step anonymous 2/6 http://localhost:8080/test_xpath.htm (HTTP 200) 
URL changed http://localhost:8080/test_xpath.htm 
[info] [phantom] Step anonymous 2/6: done in 235ms. 
[info] [phantom] Step anonymous 3/6 http://localhost:8080/test_xpath.htm (HTTP 200) 
website opened 
[info] [phantom] Step anonymous 3/6: done in 258ms. 
[info] [phantom] Step _step 4/6 http://localhost:8080/test_xpath.htm (HTTP 200) 
[info] [phantom] Step _step 4/6: done in 276ms. 
[error] [remote] findAll(): invalid selector provided "//*[text()="Click me!"]":SyntaxError: An invalid or illegal string was specified 
[error] [remote] findAll(): invalid selector provided "//*[text()="Click me!"]":SyntaxError: An invalid or illegal string was specified 
[error] [remote] findAll(): invalid selector provided "//*[text()="Click me!"]":SyntaxError: An invalid or illegal string was specified 
[error] [remote] findAll(): invalid selector provided "//*[text()="Click me!"]":SyntaxError: An invalid or illegal string was specified 
[error] [remote] findAll(): invalid selector provided "//*[text()="Click me!"]":SyntaxError: An invalid or illegal string was specified 
.... 

Я действительно не понимаю, потому что http://docs.casperjs.org/en/latest/modules/casper.html#waitforselector говорит:

Ждет, пока элемент, соответствующий предоставленному выражению выбора, существует в удаленной DOM для обработки следующего следующего шага

... w здесь http://docs.casperjs.org/en/latest/selectors.html говорит:

CasperJS делает интенсивное использование селекторов для работы с DOM, и может прозрачно использовать либо CSS3 или XPath выражений.

Таким образом, XPath должно быть в порядке - более того, я использую ТОЧНЫЙ ЖЕ XPATH в:

var aelem = __utils__.getElementByXPath('//*[text()="Click me!"]'); 

... и там он работает, но он терпит неудачу в:

casper.waitForSelector('//*[text()="Click me!"]', function() { .... 

Почему это происходит - где я ошибаюсь? И как я могу использовать этот XPath в waitForSelector, если это возможно?

ответ

3

Если вы передадите строку в функцию waitForSelector(), она будет интерпретирована как селектор CSS . Для того, чтобы иметь его работы с выражением XPath проход в object явного указания селектора type:

selectorObject = { 
    type: 'xpath', 
    path: '//*[text()="Click me!"]' 
} 
casper.waitForSelector(selectorObject, function() { 
    // ... 
}); 

Вы можете решить с waitForText(), а также, образец here.

+0

Спасибо @alecxe - как я читал документы, у меня сложилось впечатление, что 'waitForSelector' должен принимать оба; но ваш ответ, в конце концов, уточнит - будет принимать этот ответ, как только истечет время ожидания ... – sdbbs

+1

@sdbbs более тщательно просмотрел исходный код и соответствующим образом обновил ответ. Надеюсь, это поможет! – alecxe

+0

Спасибо @alecxe - просто попробовал, он отлично работает! Я бы никогда не понял это из документов; и, к сожалению, мои навыки JS - это не похвастаться, поэтому я, вероятно, посмотрел бы на источник зря ...Еще раз спасибо! – sdbbs

 Смежные вопросы

  • Нет связанных вопросов^_^