This can be reproduced by querying for nth-child with a descendant, where the descendant doesn't exist for the first matching nth-child.
This should alert "http://fiddle.jshell.net/1, http://fiddle.jshell.net/1", but actually alerts "http://fiddle.jshell.net/1, null" on Phantom:
Probably something not being cleared up after the query.
I have managed to replicate this issue, it happens when using :nth-child() in a document.querySelector API call.
var page = require('webpage').create();
page.onConsoleMessage = function(msg) {
console.log('[debug] ' + msg);
};
page.open('http://example.com', function (status) {
if(status === 'success') {
var actual = page.evaluate(function(){
var first = document.querySelector('p:nth-child(3) > a:nth-child(1)');
var second = document.querySelector('p:nth-child(3) > a:nth-child(1)');
return first === second;
});
if(!actual) {
console.error('Expected First selector to equal the Second');
} else {
console.log('Passed');
}
}
phantom.exit();
});
Expected First selector to equal the Second
This is a pretty unfortunate bug when you run into it, any timeline for when this might be fixed?
It appears to be an issue with Qt4 ported WebKit, it will not be resolved in the 1.9 version of PhantomJS. Hopefully Qt5 will have a newer WebKit port.
Any word on if this issue has been resolved?
I just ran into it and could use some help with possible solutions.
In CasperJS I worked around this by using the XPath selector instead of the CSS selector.
I just ran into this bug. Changing nth-child() to nth-of-type() fixed it for me.
Well, I thought just replacing nth-child() with nth-of-type() would always work. But it doesn't. In another case, I had to revert back to nth-child() and it WORKED!
I guess for now just try:
1) nth-child()
2) nth-of-type()
3) XPath selector (which i have not tried yet)
One hopefully will work for you until they fix it.
@mrfatboy what you suggest still doesn't work. I have created a test case that attempts your suggestion.
var page = require('webpage').create();
page.onConsoleMessage = function(msg) {
console.log('[debug] ' + msg);
};
page.open('http://example.com', function (status) {
if(status === 'success') {
var actual = page.evaluate(function(){
var selector = 'p:nth-child(3) > a:nth-child(1)';
var first = document.querySelector(selector);
var second = document.querySelector(selector);
if(second === null){
second = document.querySelector(selector.replace('nth-child', 'nth-of-type'));
if(second === null) {
second = document.querySelector(selector.replace('nth-of-type','nth-child'));
}
}
return first === second;
});
if(!actual) {
console.error('Expected First selector to equal the Second');
} else {
console.log('Passed');
}
}
phantom.exit();
});
result
$ phantomjs --version && phantomjs test.js
1.9.7
Expected First selector to equal the Second
@kylewelsby
More experimentation over the weekend revealed that method #1 and method #2 is not guaranteed. I did have to resort to method #3 (xpath) to have it work correctly. Very frustrating, I know.
Hey guys, not sure if this is useful, but I also got the issue in a few examples. For instance, consider this example:
<!DOCTYPE HTML>
<html>
<body>
<div></div>
<div>
<div>something 1</div>
<div>something 2</div>
</div>
</body>
</html>
var page = require("webpage").create();
page.open("file:///path_to_phantomscript/selector_finder01.html", function () {
var element_text = page.evaluate(function () {
return document.querySelector("body > div:nth-child(2) > div:nth-child(2)").textContent;
});
console.log(element_text);
phantom.exit();
});
The execution of the PhantomJS script throws an exception, since the element returned by the querySelector Document method call returns null,
however it is expected that the CSS selector correctly matched the DIV element with text content "something 2".
If I use the CSS selector "body > div > div:nth-child(2)", the script return the expected value of "something 2".
Just came across this bug. I'm using 1.9.8.
In 1.9.8, querying something like "ul > li:nth-child(1), ul > li:nth-child(2)" returns only the first child.
Also came across this bug: .dashboard_item .title:nth-of-type(1) returns more than one element.
I can confirm PhantomJS 2.0.0 doesn't contain this bug anymore, and this can be marked as resolved.
But it is occurring in PhantomJS 2.1.1.
Due to our very limited maintenance capacity (see #14541 for more details), we need to prioritize our development focus on other tasks. Therefore, this issue will be automatically closed. In the future, if we see the need to attend to this issue again, then it will be reopened. Thank you for your contribution!
Most helpful comment
But it is occurring in PhantomJS 2.1.1.