jasmine-headless-webkit 0.6.1 → 0.6.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +4 -0
- data/Gemfile +1 -0
- data/Guardfile +1 -1
- data/Rakefile +5 -19
- data/ext/jasmine-webkit-specrunner/HeadlessSpecRunner/ConsoleOutput.cpp +0 -0
- data/ext/jasmine-webkit-specrunner/HeadlessSpecRunner/ConsoleOutput.h +0 -0
- data/ext/jasmine-webkit-specrunner/HeadlessSpecRunner/Page.cpp +30 -0
- data/ext/jasmine-webkit-specrunner/HeadlessSpecRunner/Page.h +25 -0
- data/ext/jasmine-webkit-specrunner/HeadlessSpecRunner/Runner.cpp +270 -0
- data/ext/jasmine-webkit-specrunner/HeadlessSpecRunner/Runner.h +61 -0
- data/ext/jasmine-webkit-specrunner/extconf.rb +2 -0
- data/ext/jasmine-webkit-specrunner/specrunner.cpp +49 -410
- data/ext/jasmine-webkit-specrunner/specrunner.pro +2 -1
- data/jasmine/jasmine.headless-reporter.coffee +10 -0
- data/jasmine/jasmine.headless-reporter.js +15 -1
- data/lib/jasmine/files_list.rb +3 -6
- data/lib/jasmine/template_writer.rb +1 -0
- data/lib/jasmine-headless-webkit/version.rb +1 -1
- data/lib/jasmine-headless-webkit.rb +1 -1
- data/lib/qt/qmake.rb +25 -41
- data/spec/bin/jasmine-headless-webkit_spec.rb +0 -2
- data/spec/javascripts/jasmine.headless-reporter_spec.coffee +22 -0
- data/spec/lib/jasmine/files_list_spec.rb +3 -0
- data/spec/lib/qt/qmake_spec.rb +61 -14
- metadata +20 -57
data/.gitignore
CHANGED
data/Gemfile
CHANGED
data/Guardfile
CHANGED
data/Rakefile
CHANGED
@@ -16,31 +16,17 @@ Jasmine::Headless::Task.new
|
|
16
16
|
namespace :spec do
|
17
17
|
desc "Run on three Rubies"
|
18
18
|
task :platforms do
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
%w{1.8.7 1.9.2 ree}.each do |version|
|
23
|
-
puts "Switching to #{version}"
|
24
|
-
Bundler.with_clean_env do
|
25
|
-
system %{bash -c 'source ~/.rvm/scripts/rvm ; rvm #{version} ; bundle install ; bundle exec rake spec'}
|
26
|
-
end
|
27
|
-
if $?.exitstatus != 0
|
28
|
-
fail = true
|
29
|
-
break
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
system %{rvm #{current}}
|
34
|
-
|
35
|
-
exit (fail ? 1 : 0)
|
19
|
+
system %{rvm 1.8.7,1.9.2,ree ruby bundle}
|
20
|
+
system %{rvm 1.8.7,1.9.2,ree ruby bundle exec rake spec}
|
21
|
+
raise StandardError.new if $?.exitstatus != 0
|
36
22
|
end
|
37
23
|
end
|
38
24
|
|
39
25
|
task :default => [ 'spec:platforms', 'jasmine:headless' ]
|
40
26
|
|
41
27
|
desc "Build the runner"
|
42
|
-
task :
|
43
|
-
Dir.chdir 'ext/jasmine-
|
28
|
+
task :build_runner do
|
29
|
+
Dir.chdir 'ext/jasmine-webkit-specrunner' do
|
44
30
|
system %{ruby extconf.rb}
|
45
31
|
end
|
46
32
|
end
|
File without changes
|
File without changes
|
@@ -0,0 +1,30 @@
|
|
1
|
+
#include <QtGui>
|
2
|
+
#include <QtWebKit>
|
3
|
+
|
4
|
+
#include "Page.h"
|
5
|
+
|
6
|
+
namespace HeadlessSpecRunner {
|
7
|
+
Page::Page() : QWebPage(), confirmResult(true) {}
|
8
|
+
|
9
|
+
void Page::javaScriptConsoleMessage(const QString &message, int lineNumber, const QString &sourceID) {
|
10
|
+
emit consoleLog(message, lineNumber, sourceID);
|
11
|
+
}
|
12
|
+
|
13
|
+
bool Page::javaScriptConfirm(QWebFrame *frame, const QString &msg) {
|
14
|
+
if (confirmResult) {
|
15
|
+
emit internalLog("TODO", "jasmine-headless-webkit can't handle confirm() yet! You should mock window.confirm for now. Returning true.");
|
16
|
+
return true;
|
17
|
+
} else {
|
18
|
+
confirmResult = true;
|
19
|
+
return false;
|
20
|
+
}
|
21
|
+
}
|
22
|
+
|
23
|
+
void Page::javaScriptAlert(QWebFrame *frame, const QString &msg) {
|
24
|
+
emit internalLog("alert", msg);
|
25
|
+
}
|
26
|
+
|
27
|
+
void Page::oneFalseConfirm() {
|
28
|
+
confirmResult = false;
|
29
|
+
}
|
30
|
+
}
|
@@ -0,0 +1,25 @@
|
|
1
|
+
#ifndef JHW_PAGE
|
2
|
+
#define JHW_PAGE
|
3
|
+
|
4
|
+
#include <QtGui>
|
5
|
+
#include <QtWebKit>
|
6
|
+
|
7
|
+
namespace HeadlessSpecRunner {
|
8
|
+
class Page: public QWebPage {
|
9
|
+
Q_OBJECT
|
10
|
+
public:
|
11
|
+
Page();
|
12
|
+
void oneFalseConfirm();
|
13
|
+
signals:
|
14
|
+
void consoleLog(const QString &msg, int lineNumber, const QString &sourceID);
|
15
|
+
void internalLog(const QString ¬e, const QString &msg);
|
16
|
+
protected:
|
17
|
+
void javaScriptConsoleMessage(const QString & message, int lineNumber, const QString & sourceID);
|
18
|
+
bool javaScriptConfirm(QWebFrame *frame, const QString &msg);
|
19
|
+
void javaScriptAlert(QWebFrame *frame, const QString &msg);
|
20
|
+
private:
|
21
|
+
bool confirmResult;
|
22
|
+
};
|
23
|
+
}
|
24
|
+
|
25
|
+
#endif
|
@@ -0,0 +1,270 @@
|
|
1
|
+
#include <QtGui>
|
2
|
+
#include <QtWebKit>
|
3
|
+
#include <QFile>
|
4
|
+
#include <QTextStream>
|
5
|
+
#include <iostream>
|
6
|
+
#include <QQueue>
|
7
|
+
|
8
|
+
#include "Runner.h"
|
9
|
+
|
10
|
+
namespace HeadlessSpecRunner {
|
11
|
+
Runner::Runner() : QObject()
|
12
|
+
, m_runs(0)
|
13
|
+
, hasErrors(false)
|
14
|
+
, usedConsole(false)
|
15
|
+
, showColors(false)
|
16
|
+
, isFinished(false)
|
17
|
+
, didFail(false)
|
18
|
+
, consoleNotUsedThisRun(false) {
|
19
|
+
m_page.settings()->enablePersistentStorage();
|
20
|
+
connect(&m_page, SIGNAL(loadFinished(bool)), this, SLOT(watch(bool)));
|
21
|
+
connect(&m_page, SIGNAL(consoleLog(QString, int, QString)), this, SLOT(errorLog(QString, int, QString)));
|
22
|
+
connect(&m_page, SIGNAL(internalLog(QString, QString)), this, SLOT(internalLog(QString, QString)));
|
23
|
+
connect(m_page.mainFrame(), SIGNAL(javaScriptWindowObjectCleared()), this, SLOT(addJHW()));
|
24
|
+
}
|
25
|
+
|
26
|
+
void Runner::addFile(const QString &spec) {
|
27
|
+
runnerFiles.enqueue(spec);
|
28
|
+
}
|
29
|
+
|
30
|
+
void Runner::go()
|
31
|
+
{
|
32
|
+
m_ticker.stop();
|
33
|
+
m_page.setPreferredContentsSize(QSize(1024, 600));
|
34
|
+
addJHW();
|
35
|
+
loadSpec();
|
36
|
+
}
|
37
|
+
void Runner::addJHW()
|
38
|
+
{
|
39
|
+
m_page.mainFrame()->addToJavaScriptWindowObject("JHW", this);
|
40
|
+
}
|
41
|
+
|
42
|
+
void Runner::loadSpec()
|
43
|
+
{
|
44
|
+
m_page.mainFrame()->load(runnerFiles.dequeue());
|
45
|
+
m_ticker.start(200, this);
|
46
|
+
}
|
47
|
+
|
48
|
+
void Runner::watch(bool ok)
|
49
|
+
{
|
50
|
+
if (!ok) {
|
51
|
+
std::cerr << "Can't load " << qPrintable(m_page.mainFrame()->url().toString()) << ", the file may be broken." << std::endl;
|
52
|
+
std::cerr << "Out of curiosity, did your tests try to submit a form and you haven't prevented that?" << std::endl;
|
53
|
+
std::cerr << "Try running your tests in your browser with the Jasmine server and see what happens." << std::endl;
|
54
|
+
QApplication::instance()->exit(1);
|
55
|
+
return;
|
56
|
+
}
|
57
|
+
|
58
|
+
m_ticker.start(200, this);
|
59
|
+
}
|
60
|
+
|
61
|
+
bool Runner::hasElement(const char *select)
|
62
|
+
{
|
63
|
+
return !m_page.mainFrame()->findFirstElement(select).isNull();
|
64
|
+
}
|
65
|
+
|
66
|
+
void Runner::setColors(bool colors)
|
67
|
+
{
|
68
|
+
showColors = colors;
|
69
|
+
}
|
70
|
+
|
71
|
+
void Runner::reportFile(const QString &file)
|
72
|
+
{
|
73
|
+
reportFilename = file;
|
74
|
+
}
|
75
|
+
|
76
|
+
void Runner::red()
|
77
|
+
{
|
78
|
+
if (showColors) std::cout << "\033[0;31m";
|
79
|
+
}
|
80
|
+
|
81
|
+
void Runner::green()
|
82
|
+
{
|
83
|
+
if (showColors) std::cout << "\033[0;32m";
|
84
|
+
}
|
85
|
+
|
86
|
+
bool Runner::hasError() {
|
87
|
+
return hasErrors;
|
88
|
+
}
|
89
|
+
|
90
|
+
void Runner::yellow()
|
91
|
+
{
|
92
|
+
if (showColors) std::cout << "\033[0;33m";
|
93
|
+
}
|
94
|
+
|
95
|
+
void Runner::clear()
|
96
|
+
{
|
97
|
+
if (showColors) std::cout << "\033[m";
|
98
|
+
}
|
99
|
+
|
100
|
+
void Runner::specPassed()
|
101
|
+
{
|
102
|
+
consoleNotUsedThisRun = true;
|
103
|
+
green();
|
104
|
+
std::cout << '.';
|
105
|
+
clear();
|
106
|
+
fflush(stdout);
|
107
|
+
}
|
108
|
+
|
109
|
+
void Runner::specFailed(const QString &specDetail)
|
110
|
+
{
|
111
|
+
consoleNotUsedThisRun = true;
|
112
|
+
didFail = true;
|
113
|
+
red();
|
114
|
+
std::cout << 'F';
|
115
|
+
failedSpecs.push(specDetail);
|
116
|
+
clear();
|
117
|
+
fflush(stdout);
|
118
|
+
}
|
119
|
+
|
120
|
+
void Runner::errorLog(const QString &msg, int lineNumber, const QString &sourceID)
|
121
|
+
{
|
122
|
+
red();
|
123
|
+
std::cout << "[error] ";
|
124
|
+
clear();
|
125
|
+
std::cout << qPrintable(sourceID) << ":" << lineNumber << " : " << qPrintable(msg);
|
126
|
+
std::cout << std::endl;
|
127
|
+
|
128
|
+
hasErrors = true;
|
129
|
+
m_runs = 0;
|
130
|
+
m_ticker.start(200, this);
|
131
|
+
}
|
132
|
+
|
133
|
+
void Runner::internalLog(const QString ¬e, const QString &msg) {
|
134
|
+
red();
|
135
|
+
std::cout << "[" << qPrintable(note) << "] ";
|
136
|
+
clear();
|
137
|
+
std::cout << qPrintable(msg);
|
138
|
+
std::cout << std::endl;
|
139
|
+
}
|
140
|
+
|
141
|
+
void Runner::log(const QString &msg)
|
142
|
+
{
|
143
|
+
usedConsole = true;
|
144
|
+
green();
|
145
|
+
if (consoleNotUsedThisRun) {
|
146
|
+
std::cout << std::endl;
|
147
|
+
consoleNotUsedThisRun = false;
|
148
|
+
}
|
149
|
+
std::cout << "[console] ";
|
150
|
+
clear();
|
151
|
+
if (msg.contains("\n"))
|
152
|
+
std::cout << std::endl;
|
153
|
+
std::cout << qPrintable(msg);
|
154
|
+
std::cout << std::endl;
|
155
|
+
}
|
156
|
+
|
157
|
+
void Runner::leavePageAttempt(const QString &msg)
|
158
|
+
{
|
159
|
+
red();
|
160
|
+
std::cout << "[error] ";
|
161
|
+
clear();
|
162
|
+
std::cout << qPrintable(msg) << std::endl;
|
163
|
+
m_page.oneFalseConfirm();
|
164
|
+
hasErrors = true;
|
165
|
+
}
|
166
|
+
|
167
|
+
void Runner::printName(const QString &name)
|
168
|
+
{
|
169
|
+
std::cout << std::endl << std::endl;
|
170
|
+
red();
|
171
|
+
std::cout << qPrintable(name) << std::endl;
|
172
|
+
clear();
|
173
|
+
}
|
174
|
+
|
175
|
+
void Runner::printResult(const QString &result)
|
176
|
+
{
|
177
|
+
red();
|
178
|
+
std::cout << " " << qPrintable(result) << std::endl;
|
179
|
+
clear();
|
180
|
+
}
|
181
|
+
|
182
|
+
void Runner::finishSuite(const QString &duration, const QString &total, const QString& failed)
|
183
|
+
{
|
184
|
+
std::cout << std::endl;
|
185
|
+
if (didFail) {
|
186
|
+
red();
|
187
|
+
std::cout << "FAIL: ";
|
188
|
+
} else {
|
189
|
+
green();
|
190
|
+
std::cout << "PASS";
|
191
|
+
|
192
|
+
if (hasErrors) {
|
193
|
+
std::cout << " with JS errors";
|
194
|
+
}
|
195
|
+
|
196
|
+
std::cout << ": ";
|
197
|
+
}
|
198
|
+
|
199
|
+
std::cout << qPrintable(total) << " tests, " << qPrintable(failed) << " failures, " << qPrintable(duration) << " secs.";
|
200
|
+
clear();
|
201
|
+
std::cout << std::endl;
|
202
|
+
|
203
|
+
if (!reportFilename.isEmpty()) {
|
204
|
+
QFile reportFH(reportFilename);
|
205
|
+
|
206
|
+
if (reportFH.open(QFile::WriteOnly)) {
|
207
|
+
QTextStream report(&reportFH);
|
208
|
+
report << qPrintable(total) << "/" << qPrintable(failed) << "/";
|
209
|
+
report << (usedConsole ? "T" : "F");
|
210
|
+
report << "/" << qPrintable(duration) << "\n";
|
211
|
+
|
212
|
+
QString failedSpec;
|
213
|
+
|
214
|
+
while (!failedSpecs.isEmpty()) {
|
215
|
+
failedSpec = failedSpecs.pop();
|
216
|
+
report << qPrintable(failedSpec) << "\n";
|
217
|
+
}
|
218
|
+
|
219
|
+
reportFH.close();
|
220
|
+
}
|
221
|
+
}
|
222
|
+
|
223
|
+
isFinished = true;
|
224
|
+
}
|
225
|
+
|
226
|
+
void Runner::timerEvent(QTimerEvent *event)
|
227
|
+
{
|
228
|
+
++m_runs;
|
229
|
+
|
230
|
+
if (event->timerId() != m_ticker.timerId())
|
231
|
+
return;
|
232
|
+
|
233
|
+
if (hasErrors && m_runs > 2)
|
234
|
+
QApplication::instance()->exit(1);
|
235
|
+
|
236
|
+
if (isFinished) {
|
237
|
+
int exitCode = 0;
|
238
|
+
if (didFail || hasErrors) {
|
239
|
+
exitCode = 1;
|
240
|
+
} else {
|
241
|
+
if (usedConsole) {
|
242
|
+
exitCode = 2;
|
243
|
+
}
|
244
|
+
}
|
245
|
+
|
246
|
+
bool runAgain = true;
|
247
|
+
|
248
|
+
if (runnerFiles.count() == 0) {
|
249
|
+
runAgain = false;
|
250
|
+
} else {
|
251
|
+
if (exitCode == 1) {
|
252
|
+
runAgain = false;
|
253
|
+
}
|
254
|
+
}
|
255
|
+
|
256
|
+
if (runAgain) {
|
257
|
+
isFinished = false;
|
258
|
+
loadSpec();
|
259
|
+
} else {
|
260
|
+
QApplication::instance()->exit(exitCode);
|
261
|
+
}
|
262
|
+
}
|
263
|
+
|
264
|
+
if (m_runs > 30) {
|
265
|
+
std::cout << "WARNING: too many runs and the test is still not finished!" << std::endl;
|
266
|
+
QApplication::instance()->exit(1);
|
267
|
+
}
|
268
|
+
}
|
269
|
+
}
|
270
|
+
|
@@ -0,0 +1,61 @@
|
|
1
|
+
#ifndef JHW_RUNNER
|
2
|
+
#define JHW_RUNNER
|
3
|
+
|
4
|
+
#include <QtGui>
|
5
|
+
#include <QtWebKit>
|
6
|
+
#include <QFile>
|
7
|
+
#include <QTextStream>
|
8
|
+
#include <iostream>
|
9
|
+
#include <QQueue>
|
10
|
+
|
11
|
+
#include "Page.h"
|
12
|
+
|
13
|
+
namespace HeadlessSpecRunner {
|
14
|
+
class Runner: public QObject {
|
15
|
+
Q_OBJECT
|
16
|
+
public:
|
17
|
+
Runner();
|
18
|
+
void setColors(bool colors);
|
19
|
+
void reportFile(const QString &file);
|
20
|
+
void addFile(const QString &spec);
|
21
|
+
void go();
|
22
|
+
public slots:
|
23
|
+
void log(const QString &msg);
|
24
|
+
bool hasError();
|
25
|
+
void leavePageAttempt(const QString &msg);
|
26
|
+
void specPassed();
|
27
|
+
void specFailed(const QString &specDetail);
|
28
|
+
void printName(const QString &name);
|
29
|
+
void printResult(const QString &result);
|
30
|
+
void finishSuite(const QString &duration, const QString &total, const QString& failed);
|
31
|
+
private slots:
|
32
|
+
void watch(bool ok);
|
33
|
+
void errorLog(const QString &msg, int lineNumber, const QString &sourceID);
|
34
|
+
void internalLog(const QString ¬e, const QString &msg);
|
35
|
+
void addJHW();
|
36
|
+
protected:
|
37
|
+
bool hasElement(const char *select);
|
38
|
+
void timerEvent(QTimerEvent *event);
|
39
|
+
private:
|
40
|
+
HeadlessSpecRunner::Page m_page;
|
41
|
+
QBasicTimer m_ticker;
|
42
|
+
int m_runs;
|
43
|
+
bool hasErrors;
|
44
|
+
bool usedConsole;
|
45
|
+
bool showColors;
|
46
|
+
bool isFinished;
|
47
|
+
bool didFail;
|
48
|
+
bool consoleNotUsedThisRun;
|
49
|
+
QQueue<QString> runnerFiles;
|
50
|
+
QString reportFilename;
|
51
|
+
QStack<QString> failedSpecs;
|
52
|
+
|
53
|
+
void red();
|
54
|
+
void green();
|
55
|
+
void yellow();
|
56
|
+
void clear();
|
57
|
+
void loadSpec();
|
58
|
+
};
|
59
|
+
}
|
60
|
+
|
61
|
+
#endif
|