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 CHANGED
@@ -6,3 +6,7 @@ Makefile
6
6
  specrunner.moc
7
7
  specrunner.o
8
8
  ext/jasmine-webkit-specrunner/jasmine-webkit-specrunner
9
+ *.o
10
+ moc_*.*
11
+ .DS_Store
12
+ hydra-runner.log
data/Gemfile CHANGED
@@ -12,3 +12,4 @@ gem 'guard-coffeescript'
12
12
  gem 'growl'
13
13
  gem 'rake', '0.8.7'
14
14
  gem 'mocha', '0.9.12'
15
+ gem 'guard-jasmine-headless-webkit'
data/Guardfile CHANGED
@@ -4,7 +4,7 @@
4
4
  #
5
5
 
6
6
  guard 'shell' do
7
- watch(%r{ext/jasmine-webkit-specrunner/specrunner.cpp}) { compile }
7
+ watch(%r{ext/jasmine-webkit-specrunner/.*\.(cpp|h)}) { compile }
8
8
  end
9
9
  # A sample Guardfile
10
10
  # More info at https://github.com/guard/guard#readme
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
- current = %x{rvm-prompt v}
20
-
21
- fail = false
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 :build do
43
- Dir.chdir 'ext/jasmine-headless-specrunner' do
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
@@ -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 &note, 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 &note, 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 &note, 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
@@ -1,3 +1,5 @@
1
+ require 'fileutils'
2
+
1
3
  $: << File.expand_path("../../../lib", __FILE__)
2
4
 
3
5
  require 'qt/qmake'