This error message...
WebDriverException: target frame detached
...implies that a resultant HttpServerResponseInfo was net::HTTP_NOT_FOUND.
Details
As per the discussion Some error codes are not standard compliant there are some Chrome-specific error codes which still exists and most clients will treat them as unknown error
. These error codes are:
target frame detached
chrome not reachable
disconnected
forbidden
no such execution context
tab crashed
This issue was addressed through the bug / commit and the current status is ToBeReleased.
Deep Dive
The error target frame detached is defined in case kTargetDetached where case kTargetDetached
is defined in http_handler.cc and occurs when the HttpServerResponseInfo contains HTTP_NOT_FOUND
as follows:
void HttpHandler::HandleCommand(
const net::HttpServerRequestInfo& request,
const std::string& trimmed_path,
const HttpResponseSenderFunc& send_response_func) {
base::DictionaryValue params;
std::string session_id;
CommandMap::const_iterator iter = command_map_->begin();
while (true) {
if (iter == command_map_->end()) {
if (w3cMode(session_id, session_thread_map_)) {
PrepareResponse(
trimmed_path, send_response_func,
Status(kUnknownCommand, "unknown command: " + trimmed_path),
nullptr, session_id, true);
} else {
std::unique_ptr<net::HttpServerResponseInfo> response(
new net::HttpServerResponseInfo(net::HTTP_NOT_FOUND));
response->SetBody("unknown command: " + trimmed_path, "text/plain");
send_response_func.Run(std::move(response));
}
return;
}
if (internal::MatchesCommand(
request.method, trimmed_path, *iter, &session_id, ¶ms)) {
break;
}
++iter;
}
and most possibly the reason in your case is kTargetDetached:
case kTargetDetached:
response.reset(new net::HttpServerResponseInfo(net::HTTP_NOT_FOUND));
break;
Solution
To switch Selenium's focus within an <iframe>
you have to induce WebDriverWait for the desired frame to be available and switch to it as follows:
Using CssSelector:
new WebDriverWait(driver, TimeSpan.FromSeconds(20)).Until(ExpectedConditions.FrameToBeAvailableAndSwitchToIt(By.CssSelector("iframe#twitter-widget-0")));
Using XPath:
new WebDriverWait(driver, TimeSpan.FromSeconds(20)).Until(ExpectedConditions.FrameToBeAvailableAndSwitchToIt(By.XPath("//fieldset[@id='twitter-widget-0']")));
Reference
You can find a couple of relevant discussions in:
Outro
Ways to deal with #document under iframe