Support Capybara 2.11
* Update versions being tested against * Implement missing APIs from newer versions
This commit is contained in:
parent
b22df5fe67
commit
43ebe80704
|
@ -25,18 +25,18 @@ addons:
|
|||
matrix:
|
||||
include:
|
||||
- rvm: 1.9.3
|
||||
gemfile: gemfiles/2.6.gemfile
|
||||
gemfile: gemfiles/2.7.gemfile
|
||||
env: QMAKE=/usr/lib/x86_64-linux-gnu/qt4/bin/qmake
|
||||
- rvm: 1.9.3
|
||||
gemfile: gemfiles/2.5.gemfile
|
||||
gemfile: gemfiles/2.11.gemfile
|
||||
env: QMAKE=/usr/lib/x86_64-linux-gnu/qt4/bin/qmake
|
||||
- rvm: 2.3.1
|
||||
gemfile: gemfiles/master.gemfile
|
||||
allow_failures:
|
||||
- gemfile: gemfiles/master.gemfile
|
||||
gemfile:
|
||||
- gemfiles/2.6.gemfile
|
||||
- gemfiles/2.5.gemfile
|
||||
- gemfiles/2.7.gemfile
|
||||
- gemfiles/2.11.gemfile
|
||||
before_install:
|
||||
- gem install bundler
|
||||
install: bundle
|
||||
|
|
12
Appraisals
12
Appraisals
|
@ -1,9 +1,13 @@
|
|||
appraise "2.6" do
|
||||
gem "capybara", "~> 2.6.0"
|
||||
end
|
||||
|
||||
appraise "2.7" do
|
||||
gem "capybara", "~> 2.7.0"
|
||||
gem 'addressable', '< 2.5.0', :platforms=>[:ruby_19, :jruby_19] # 2.5 requires public_suffix which requires ruby 2.0
|
||||
gem 'nokogiri', '< 1.7.0', :platforms=>[:ruby_19, :jruby_19] # 1.7.0 requires ruby 2.1+
|
||||
end
|
||||
|
||||
appraise "2.11" do
|
||||
gem "capybara", "~> 2.11.0"
|
||||
gem 'addressable', '< 2.5.0', :platforms=>[:ruby_19, :jruby_19] # 2.5 requires public_suffix which requires ruby 2.0
|
||||
gem 'nokogiri', '< 1.7.0', :platforms=>[:ruby_19, :jruby_19] # 1.7.0 requires ruby 2.1+
|
||||
end
|
||||
|
||||
appraise "master" do
|
||||
|
|
87
Gemfile.lock
87
Gemfile.lock
|
@ -2,70 +2,63 @@ PATH
|
|||
remote: .
|
||||
specs:
|
||||
capybara-webkit (1.11.1)
|
||||
capybara (>= 2.3.0, < 2.8.0)
|
||||
capybara (>= 2.3.0, < 2.13.0)
|
||||
json
|
||||
|
||||
GEM
|
||||
remote: https://rubygems.org/
|
||||
specs:
|
||||
addressable (2.3.6)
|
||||
appraisal (0.4.0)
|
||||
addressable (2.5.0)
|
||||
public_suffix (~> 2.0, >= 2.0.2)
|
||||
appraisal (0.4.1)
|
||||
bundler
|
||||
rake
|
||||
capybara (2.5.0)
|
||||
capybara (2.11.0)
|
||||
addressable
|
||||
mime-types (>= 1.16)
|
||||
nokogiri (>= 1.3.3)
|
||||
rack (>= 1.0.0)
|
||||
rack-test (>= 0.5.4)
|
||||
xpath (~> 2.0)
|
||||
childprocess (0.5.5)
|
||||
ffi (~> 1.0, >= 1.0.11)
|
||||
diff-lcs (1.2.4)
|
||||
ffi (1.9.8)
|
||||
ffi (1.9.8-java)
|
||||
ffi (1.9.8-x86-mingw32)
|
||||
diff-lcs (1.2.5)
|
||||
ffi (1.9.14-java)
|
||||
json (1.8.3)
|
||||
launchy (2.4.2)
|
||||
json (1.8.3-java)
|
||||
launchy (2.4.3)
|
||||
addressable (~> 2.3)
|
||||
launchy (2.4.2-java)
|
||||
launchy (2.4.3-java)
|
||||
addressable (~> 2.3)
|
||||
spoon (~> 0.0.1)
|
||||
mime-types (2.6.1)
|
||||
mini_magick (3.2.1)
|
||||
subexec (~> 0.0.4)
|
||||
mini_portile2 (2.0.0)
|
||||
multi_json (1.11.0)
|
||||
nokogiri (1.6.7.2)
|
||||
mini_portile2 (~> 2.0.0.rc2)
|
||||
rack (1.6.4)
|
||||
rack-protection (1.3.2)
|
||||
mime-types (2.99.3)
|
||||
mini_magick (4.6.0)
|
||||
mini_portile2 (2.1.0)
|
||||
nokogiri (1.7.0.1)
|
||||
mini_portile2 (~> 2.1.0)
|
||||
nokogiri (1.7.0.1-java)
|
||||
nokogiri (1.7.0.1-x86-mingw32)
|
||||
mini_portile2 (~> 2.1.0)
|
||||
public_suffix (2.0.5)
|
||||
rack (1.6.5)
|
||||
rack-protection (1.5.3)
|
||||
rack
|
||||
rack-test (0.6.3)
|
||||
rack (>= 1.0)
|
||||
rake (0.9.2)
|
||||
rspec (2.14.1)
|
||||
rspec-core (~> 2.14.0)
|
||||
rspec-expectations (~> 2.14.0)
|
||||
rspec-mocks (~> 2.14.0)
|
||||
rspec-core (2.14.4)
|
||||
rspec-expectations (2.14.1)
|
||||
rake (11.3.0)
|
||||
rspec (2.99.0)
|
||||
rspec-core (~> 2.99.0)
|
||||
rspec-expectations (~> 2.99.0)
|
||||
rspec-mocks (~> 2.99.0)
|
||||
rspec-core (2.99.2)
|
||||
rspec-expectations (2.99.2)
|
||||
diff-lcs (>= 1.1.3, < 2.0)
|
||||
rspec-mocks (2.14.3)
|
||||
rubyzip (1.1.7)
|
||||
selenium-webdriver (2.45.0)
|
||||
childprocess (~> 0.5)
|
||||
multi_json (~> 1.0)
|
||||
rubyzip (~> 1.0)
|
||||
websocket (~> 1.0)
|
||||
sinatra (1.3.5)
|
||||
rack (~> 1.4)
|
||||
rack-protection (~> 1.3)
|
||||
tilt (~> 1.3, >= 1.3.3)
|
||||
spoon (0.0.4)
|
||||
rspec-mocks (2.99.4)
|
||||
sinatra (1.4.7)
|
||||
rack (~> 1.5)
|
||||
rack-protection (~> 1.4)
|
||||
tilt (>= 1.3, < 3)
|
||||
spoon (0.0.6)
|
||||
ffi
|
||||
subexec (0.0.4)
|
||||
tilt (1.3.3)
|
||||
websocket (1.2.1)
|
||||
tilt (2.0.5)
|
||||
xpath (2.0.0)
|
||||
nokogiri (~> 1.3)
|
||||
|
||||
|
@ -77,13 +70,13 @@ PLATFORMS
|
|||
DEPENDENCIES
|
||||
appraisal (~> 0.4.0)
|
||||
capybara-webkit!
|
||||
json (< 2.0)
|
||||
launchy
|
||||
mime-types (< 3.0)
|
||||
mini_magick
|
||||
rake
|
||||
rspec (~> 2.14.0)
|
||||
selenium-webdriver
|
||||
rake (< 12.0.0)
|
||||
rspec (~> 2.14)
|
||||
sinatra
|
||||
|
||||
BUNDLED WITH
|
||||
1.11.2
|
||||
1.13.6
|
||||
|
|
|
@ -21,16 +21,15 @@ Gem::Specification.new do |s|
|
|||
|
||||
s.requirements << "Qt >= 4.8"
|
||||
|
||||
s.add_runtime_dependency("capybara", ">= 2.3.0", "< 2.8.0")
|
||||
s.add_runtime_dependency("capybara", ">= 2.3.0", "< 2.13.0")
|
||||
s.add_runtime_dependency("json")
|
||||
|
||||
s.add_development_dependency("rspec", "~> 2.14.0")
|
||||
s.add_development_dependency("rspec", "~> 2.14")
|
||||
# Sinatra is used by Capybara's TestApp
|
||||
s.add_development_dependency("sinatra")
|
||||
s.add_development_dependency("mini_magick")
|
||||
s.add_development_dependency("rake")
|
||||
s.add_development_dependency("rake", "< 12.0.0")
|
||||
s.add_development_dependency("appraisal", "~> 0.4.0")
|
||||
s.add_development_dependency("selenium-webdriver")
|
||||
s.add_development_dependency("launchy")
|
||||
end
|
||||
|
||||
|
|
|
@ -4,7 +4,8 @@ source "https://rubygems.org"
|
|||
|
||||
gem "mime-types", "< 3.0", :platforms=>[:ruby_19, :jruby_19]
|
||||
gem "json", "< 2.0", :platforms=>[:ruby_19, :jruby_19]
|
||||
|
||||
gem "capybara", "~> 2.6.0"
|
||||
gem "capybara", "~> 2.11.0"
|
||||
gem "addressable", "< 2.5.0", :platforms=>[:ruby_19, :jruby_19]
|
||||
gem "nokogiri", "< 1.7.0", :platforms=>[:ruby_19, :jruby_19]
|
||||
|
||||
gemspec :path=>"../"
|
|
@ -4,7 +4,8 @@ source "https://rubygems.org"
|
|||
|
||||
gem "mime-types", "< 3.0", :platforms=>[:ruby_19, :jruby_19]
|
||||
gem "json", "< 2.0", :platforms=>[:ruby_19, :jruby_19]
|
||||
|
||||
gem "capybara", "~> 2.7.0"
|
||||
gem "addressable", "< 2.5.0", :platforms=>[:ruby_19, :jruby_19]
|
||||
gem "nokogiri", "< 1.7.0", :platforms=>[:ruby_19, :jruby_19]
|
||||
|
||||
gemspec :path=>"../"
|
|
@ -4,7 +4,6 @@ source "https://rubygems.org"
|
|||
|
||||
gem "mime-types", "< 3.0", :platforms=>[:ruby_19, :jruby_19]
|
||||
gem "json", "< 2.0", :platforms=>[:ruby_19, :jruby_19]
|
||||
|
||||
gem "capybara", :github=>"jnicklas/capybara"
|
||||
|
||||
gemspec :path=>"../"
|
|
@ -223,13 +223,13 @@ https://github.com/thoughtbot/capybara-webkit/wiki/Reporting-Crashes
|
|||
MESSAGE
|
||||
end
|
||||
|
||||
def evaluate_script(script)
|
||||
json = command('Evaluate', script)
|
||||
def evaluate_script(script, *args)
|
||||
json = command('Evaluate', script, args.to_json)
|
||||
JSON.parse("[#{json}]").first
|
||||
end
|
||||
|
||||
def execute_script(script)
|
||||
command('Execute', script)
|
||||
def execute_script(script, *args)
|
||||
command('Execute', script, args.to_json)
|
||||
end
|
||||
|
||||
def render(path, width, height)
|
||||
|
|
|
@ -76,13 +76,18 @@ module Capybara::Webkit
|
|||
@browser.title
|
||||
end
|
||||
|
||||
def execute_script(script)
|
||||
value = @browser.execute_script script
|
||||
value.empty? ? nil : value
|
||||
def execute_script(script, *args)
|
||||
value = @browser.execute_script(script, *encode_args(args))
|
||||
|
||||
if value.empty?
|
||||
nil
|
||||
else
|
||||
value
|
||||
end
|
||||
end
|
||||
|
||||
def evaluate_script(script)
|
||||
@browser.evaluate_script script
|
||||
def evaluate_script(script, *args)
|
||||
@browser.evaluate_script(script, *encode_args(args))
|
||||
end
|
||||
|
||||
def console_messages
|
||||
|
@ -144,6 +149,21 @@ module Capybara::Webkit
|
|||
end
|
||||
end
|
||||
|
||||
def switch_to_frame(frame)
|
||||
case frame
|
||||
when :top
|
||||
begin
|
||||
loop { @browser.frame_focus }
|
||||
rescue Capybara::Webkit::InvalidResponseError => e
|
||||
raise unless e.message =~ /Already at parent frame/
|
||||
end
|
||||
when :parent
|
||||
@browser.frame_focus
|
||||
else
|
||||
@browser.frame_focus(frame)
|
||||
end
|
||||
end
|
||||
|
||||
def within_window(selector)
|
||||
current_window = current_window_handle
|
||||
switch_to_window(selector)
|
||||
|
@ -391,5 +411,15 @@ module Capybara::Webkit
|
|||
"This option is global and can be configured once" \
|
||||
" (not in a `before` or `setup` block)."
|
||||
end
|
||||
|
||||
def encode_args(args)
|
||||
args.map do |arg|
|
||||
if arg.is_a?(Capybara::Webkit::Node)
|
||||
{ ELEMENT: arg.native }.to_json
|
||||
else
|
||||
arg.to_json
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -114,11 +114,13 @@ module Capybara::Webkit
|
|||
end
|
||||
|
||||
def disabled?
|
||||
if %w(option optgroup).include? tag_name
|
||||
self['disabled'] || find_xpath("parent::*")[0].disabled?
|
||||
else
|
||||
self['disabled']
|
||||
end
|
||||
xpath = "parent::optgroup[@disabled] | " \
|
||||
"ancestor::select[@disabled] | " \
|
||||
"parent::fieldset[@disabled] | " \
|
||||
"ancestor::*[not(self::legend) or " \
|
||||
"preceding-sibling::legend][parent::fieldset[@disabled]]"
|
||||
|
||||
self["disabled"] || !find_xpath(xpath).empty?
|
||||
end
|
||||
|
||||
def path
|
||||
|
|
|
@ -62,12 +62,25 @@ describe Capybara::Webkit::Driver do
|
|||
</head>
|
||||
<body>
|
||||
<script type="text/javascript">
|
||||
document.write("<p id='farewell'>goodbye</p>");
|
||||
document.write("<p id='farewell'>goodbye</p><iframe id='g' src='/iframe2'></iframe>");
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
HTML
|
||||
end
|
||||
|
||||
get '/iframe2' do
|
||||
<<-HTML
|
||||
<html>
|
||||
<head>
|
||||
<title>Frame 2</title>
|
||||
</head>
|
||||
<body>
|
||||
<div>In frame 2</div>
|
||||
</body>
|
||||
</html>
|
||||
HTML
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -95,6 +108,37 @@ describe Capybara::Webkit::Driver do
|
|||
end
|
||||
end
|
||||
|
||||
it "switches to frame by element" do
|
||||
frame = driver.find_xpath('//iframe').first
|
||||
element = double(Capybara::Node::Base, base: frame)
|
||||
driver.switch_to_frame(element)
|
||||
driver.find_xpath("//*[contains(., 'goodbye')]").should_not be_empty
|
||||
driver.switch_to_frame(:parent)
|
||||
end
|
||||
|
||||
it "can switch back to the parent frame" do
|
||||
frame = driver.find_xpath('//iframe').first
|
||||
element = double(Capybara::Node::Base, base: frame)
|
||||
driver.switch_to_frame(element)
|
||||
driver.switch_to_frame(:parent)
|
||||
driver.find_xpath("//*[contains(., 'greeting')]").should_not be_empty
|
||||
driver.find_xpath("//*[contains(., 'goodbye')]").should be_empty
|
||||
end
|
||||
|
||||
it "can switch to the top frame" do
|
||||
frame = driver.find_xpath('//iframe').first
|
||||
element = double(Capybara::Node::Base, base: frame)
|
||||
driver.switch_to_frame(element)
|
||||
frame2 = driver.find_xpath('//iframe[@id="g"]').first
|
||||
element2 = double(Capybara::Node::Base, base: frame2)
|
||||
driver.switch_to_frame(element2)
|
||||
driver.find_xpath("//div[contains(., 'In frame 2')]").should_not be_empty
|
||||
driver.switch_to_frame(:top)
|
||||
driver.find_xpath("//*[contains(., 'greeting')]").should_not be_empty
|
||||
driver.find_xpath("//*[contains(., 'goodbye')]").should be_empty
|
||||
driver.find_xpath("//div[contains(., 'In frame 2')]").should be_empty
|
||||
end
|
||||
|
||||
it "raises error for missing frame by index" do
|
||||
expect { driver.within_frame(1) { } }.
|
||||
to raise_error(Capybara::Webkit::InvalidResponseError)
|
||||
|
@ -528,6 +572,38 @@ describe Capybara::Webkit::Driver do
|
|||
to raise_error(Capybara::Webkit::InvalidResponseError)
|
||||
end
|
||||
|
||||
it "passes arguments to executed Javascript" do
|
||||
driver.execute_script(%<document.getElementById('greeting').innerHTML = arguments[0]>, "My argument")
|
||||
driver.find_xpath("//p[contains(., 'My argument')]").should_not be_empty
|
||||
end
|
||||
|
||||
it "passes multiple arguments to executed Javascript" do
|
||||
driver.execute_script(
|
||||
%<document.getElementById('greeting').innerHTML = arguments[0] + arguments[1] + arguments[2].color>,
|
||||
"random", 4, {color: 'red'})
|
||||
driver.find_xpath("//p[contains(., 'random4red')]").should_not be_empty
|
||||
end
|
||||
|
||||
it "passes page elements to executed Javascript" do
|
||||
greeting = driver.find_xpath("//p[@id='greeting']").first
|
||||
driver.execute_script(%<arguments[0].innerHTML = arguments[1]>, greeting, "new content")
|
||||
driver.find_xpath("//p[@id='greeting'][contains(., 'new content')]").should_not be_empty
|
||||
end
|
||||
|
||||
it "passes arguments to evaaluated Javascript" do
|
||||
driver.evaluate_script(%<arguments[0]>, 3).should eq 3
|
||||
end
|
||||
|
||||
it "passes multiple arguments to evaluated Javascript" do
|
||||
driver.evaluate_script(%<arguments[0] + arguments[1] + arguments[2].num>, 3, 4, {num: 5}).should eq 12
|
||||
end
|
||||
|
||||
it "passes page elements to evaluated Javascript" do
|
||||
greeting = driver.find_xpath("//p[@id='greeting']").first
|
||||
driver.evaluate_script(%<arguments[1].innerHTML = arguments[0]; arguments[2]>, "newer content", greeting, 7).should eq 7
|
||||
driver.find_xpath("//p[@id='greeting'][contains(., 'newer content')]").should_not be_empty
|
||||
end
|
||||
|
||||
it "doesn't raise an error for Javascript that doesn't return anything" do
|
||||
lambda { driver.execute_script(%<(function () { "returns nothing" })()>) }.
|
||||
should_not raise_error
|
||||
|
|
|
@ -8,7 +8,26 @@ Evaluate::Evaluate(WebPageManager *manager, QStringList &arguments, QObject *par
|
|||
}
|
||||
|
||||
void Evaluate::start() {
|
||||
QVariant result = page()->currentFrame()->evaluateJavaScript(arguments()[0]);
|
||||
QString script = arguments()[0];
|
||||
QString jsonArgs;
|
||||
if (arguments().length()>1){
|
||||
jsonArgs = arguments()[1];
|
||||
} else {
|
||||
jsonArgs ="[]";
|
||||
}
|
||||
QString eval_script = QString("(function(){"
|
||||
" for(var i=0; i<arguments.length; i++) {"
|
||||
" arguments[i] = JSON.parse(arguments[i]);"
|
||||
" if (arguments[i]['ELEMENT']) {"
|
||||
" arguments[i] = Capybara.getNode(arguments[i]['ELEMENT']);"
|
||||
" };"
|
||||
" };"
|
||||
" return eval(\"%1\");"
|
||||
" }).apply(null, %2)").arg(script.replace("\"","\\\"").remove("\n"), jsonArgs);
|
||||
QObject invocation_stub;
|
||||
invocation_stub.setProperty("allowUnattached", false);
|
||||
page()->currentFrame()->addToJavaScriptWindowObject("CapybaraInvocation", &invocation_stub);
|
||||
QVariant result = page()->currentFrame()->evaluateJavaScript(eval_script);
|
||||
JsonSerializer serializer;
|
||||
finish(true, serializer.serialize(result));
|
||||
}
|
||||
|
|
|
@ -7,7 +7,24 @@ Execute::Execute(WebPageManager *manager, QStringList &arguments, QObject *paren
|
|||
}
|
||||
|
||||
void Execute::start() {
|
||||
QString script = arguments()[0] + QString("; 'success'");
|
||||
QString jsonArgs;
|
||||
if (arguments().length()>1){
|
||||
jsonArgs = arguments()[1];
|
||||
} else {
|
||||
jsonArgs ="[]";
|
||||
}
|
||||
QString script = QString("(function(){"
|
||||
" for(var i=0; i<arguments.length; i++) {"
|
||||
" arguments[i] = JSON.parse(arguments[i]);"
|
||||
" if (arguments[i]['ELEMENT']) {"
|
||||
" arguments[i] = Capybara.getNode(arguments[i]['ELEMENT']);"
|
||||
" };"
|
||||
" };"
|
||||
" %1 }).apply(null, %2); 'success'").arg(arguments()[0], jsonArgs);
|
||||
|
||||
QObject invocation_stub;
|
||||
invocation_stub.setProperty("allowUnattached", false);
|
||||
page()->currentFrame()->addToJavaScriptWindowObject("CapybaraInvocation", &invocation_stub);
|
||||
QVariant result = page()->currentFrame()->evaluateJavaScript(script);
|
||||
if (result.isValid()) {
|
||||
finish(true);
|
||||
|
|
|
@ -8,7 +8,6 @@ FrameFocus::FrameFocus(WebPageManager *manager, QStringList &arguments, QObject
|
|||
}
|
||||
|
||||
void FrameFocus::start() {
|
||||
findFrames();
|
||||
switch(arguments().length()) {
|
||||
case 1:
|
||||
focusId(arguments()[0]);
|
||||
|
@ -26,8 +25,10 @@ void FrameFocus::findFrames() {
|
|||
}
|
||||
|
||||
void FrameFocus::focusIndex(int index) {
|
||||
findFrames();
|
||||
if (isFrameAtIndex(index)) {
|
||||
frames[index]->setFocus();
|
||||
page()->setCurrentFrameParent(frames[index]->parentFrame());
|
||||
success();
|
||||
} else {
|
||||
frameNotFound();
|
||||
|
@ -39,9 +40,11 @@ bool FrameFocus::isFrameAtIndex(int index) {
|
|||
}
|
||||
|
||||
void FrameFocus::focusId(QString name) {
|
||||
findFrames();
|
||||
for (int i = 0; i < frames.length(); i++) {
|
||||
if (frames[i]->frameName().compare(name) == 0) {
|
||||
frames[i]->setFocus();
|
||||
page()->setCurrentFrameParent(frames[i]->parentFrame());
|
||||
success();
|
||||
return;
|
||||
}
|
||||
|
@ -51,10 +54,13 @@ void FrameFocus::focusId(QString name) {
|
|||
}
|
||||
|
||||
void FrameFocus::focusParent() {
|
||||
if (page()->currentFrame()->parentFrame() == 0) {
|
||||
// if (page()->currentFrame()->parentFrame() == 0) {
|
||||
if (page()->currentFrameParent() == 0) {
|
||||
finish(false, new ErrorMessage("Already at parent frame."));
|
||||
} else {
|
||||
page()->currentFrame()->parentFrame()->setFocus();
|
||||
// page()->currentFrame()->parentFrame()->setFocus();
|
||||
page()->currentFrameParent()->setFocus();
|
||||
page()->setCurrentFrameParent(page()->currentFrameParent()->parentFrame());
|
||||
success();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,9 +37,15 @@ InvocationResult JavascriptInvocation::invoke(QWebFrame *frame) {
|
|||
QVariant result = frame->evaluateJavaScript("Capybara.invoke()");
|
||||
if (getError().isValid())
|
||||
return InvocationResult(getError(), true);
|
||||
else
|
||||
else {
|
||||
if (functionName() == "leftClick") {
|
||||
// Don't trigger the left click from JS incase the frame closes
|
||||
QVariantMap qm = result.toMap();
|
||||
leftClick(qm["absoluteX"].toInt(), qm["absoluteY"].toInt());
|
||||
}
|
||||
return InvocationResult(result);
|
||||
}
|
||||
}
|
||||
|
||||
void JavascriptInvocation::leftClick(int x, int y) {
|
||||
QPoint mousePos(x, y);
|
||||
|
|
|
@ -11,6 +11,9 @@ void Node::start() {
|
|||
QString functionName = functionArguments.takeFirst();
|
||||
QString allowUnattached = functionArguments.takeFirst();
|
||||
InvocationResult result = page()->invokeCapybaraFunction(functionName, allowUnattached == "true", functionArguments);
|
||||
if (functionName == "focus") {
|
||||
page()->setCurrentFrameParent(page()->currentFrame()->parentFrame());
|
||||
}
|
||||
finish(&result);
|
||||
}
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@ WebPage::WebPage(WebPageManager *manager, QObject *parent) : QWebPage(parent) {
|
|||
m_uuid = QUuid::createUuid().toString();
|
||||
m_confirmAction = true;
|
||||
m_promptAction = false;
|
||||
m_currentFrameParent = 0;
|
||||
|
||||
setForwardUnsupportedContent(true);
|
||||
loadJavascript();
|
||||
|
@ -255,6 +256,7 @@ bool WebPage::javaScriptPrompt(QWebFrame *frame, const QString &message, const Q
|
|||
|
||||
void WebPage::loadStarted() {
|
||||
m_loading = true;
|
||||
m_currentFrameParent = currentFrame()->parentFrame();
|
||||
m_errorPageMessage = QString();
|
||||
}
|
||||
|
||||
|
@ -485,3 +487,13 @@ void WebPage::addModalMessage(bool expectedType, const QString &message, const Q
|
|||
m_modalMessages << QString();
|
||||
emit modalReady();
|
||||
}
|
||||
|
||||
QWebFrame* WebPage::currentFrameParent() {
|
||||
return m_currentFrameParent;
|
||||
}
|
||||
|
||||
void WebPage::setCurrentFrameParent(QWebFrame* frame) {
|
||||
m_currentFrameParent = frame;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -55,6 +55,8 @@ class WebPage : public QWebPage {
|
|||
void resize(int, int);
|
||||
int modalCount();
|
||||
QString modalMessage();
|
||||
void setCurrentFrameParent(QWebFrame* frame);
|
||||
QWebFrame* currentFrameParent();
|
||||
|
||||
public slots:
|
||||
bool shouldInterruptJavaScript();
|
||||
|
@ -105,6 +107,7 @@ class WebPage : public QWebPage {
|
|||
QList<QVariantMap> m_modalResponses;
|
||||
QStringList m_modalMessages;
|
||||
void addModalMessage(bool, const QString &, const QRegExp &);
|
||||
QWebFrame* m_currentFrameParent;
|
||||
};
|
||||
|
||||
#endif //_WEBPAGE_H
|
||||
|
|
|
@ -5,7 +5,11 @@ Capybara = {
|
|||
|
||||
invoke: function () {
|
||||
try {
|
||||
if (CapybaraInvocation.functionName == "leftClick") {
|
||||
return this["verifiedClickPosition"].apply(this, CapybaraInvocation.arguments);
|
||||
} else {
|
||||
return this[CapybaraInvocation.functionName].apply(this, CapybaraInvocation.arguments);
|
||||
}
|
||||
} catch (e) {
|
||||
CapybaraInvocation.error = e;
|
||||
}
|
||||
|
@ -204,12 +208,17 @@ Capybara = {
|
|||
throw new Capybara.UnpositionedElement(this.pathForNode(node), visible);
|
||||
},
|
||||
|
||||
click: function (index, action) {
|
||||
verifiedClickPosition: function (index) {
|
||||
var node = this.getNode(index);
|
||||
node.scrollIntoViewIfNeeded();
|
||||
var pos = this.clickPosition(node);
|
||||
CapybaraInvocation.hover(pos.relativeX, pos.relativeY);
|
||||
this.expectNodeAtPosition(node, pos);
|
||||
return pos;
|
||||
},
|
||||
|
||||
click: function (index, action) {
|
||||
var pos = this.verifiedClickPosition(index);
|
||||
action(pos.absoluteX, pos.absoluteY);
|
||||
},
|
||||
|
||||
|
|
Loading…
Reference in New Issue