smalruby-editor 0.0.5 → 0.0.6
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.
Potentially problematic release.
This version of smalruby-editor might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.rspec +2 -1
- data/.rubocop.yml +18 -0
- data/.travis.yml +24 -23
- data/LEGAL +13 -0
- data/README.rdoc +1 -0
- data/Rakefile +3 -0
- data/app/assets/javascripts/application.js +1 -1
- data/app/assets/javascripts/editor.js.coffee +60 -15
- data/app/assets/stylesheets/application.css +1 -2
- data/app/assets/stylesheets/flatstrap-custom.css.scss +2 -0
- data/app/controllers/editor_controller.rb +0 -24
- data/app/controllers/source_codes_controller.rb +67 -0
- data/app/models/source_code.rb +42 -0
- data/app/views/editor/index.html.erb +5 -3
- data/bin/smalruby-editor +11 -0
- data/config/application.rb +8 -20
- data/config/boot.rb +3 -0
- data/config/environments/development.rb +2 -1
- data/config/environments/production.rb +12 -6
- data/config/environments/standalone.rb +3 -2
- data/config/environments/test.rb +14 -4
- data/config/initializers/backtrace_silencers.rb +4 -2
- data/config/initializers/session_store.rb +2 -1
- data/config/initializers/wrap_parameters.rb +2 -1
- data/config/routes.rb +10 -6
- data/config/unicorn.rb +7 -6
- data/db/migrate/20131216121603_create_source_codes.rb +9 -0
- data/db/migrate/20131219045113_add_filename_to_source_code.rb +5 -0
- data/db/schema.rb +8 -1
- data/lib/smalruby_editor.rb +29 -15
- data/lib/smalruby_editor/version.rb +1 -1
- data/lib/tasks/rspec.rake +2 -2
- data/lib/tasks/rubocop.rake +3 -0
- data/public/fonts/FontAwesome.otf +0 -0
- data/public/fonts/fontawesome-webfont.eot +0 -0
- data/public/fonts/fontawesome-webfont.ttf +0 -0
- data/public/fonts/fontawesome-webfont.woff +0 -0
- data/smalruby-editor.gemspec +3 -3
- data/spec/acceptance/readme.md +3 -0
- data/spec/acceptance/text_editor/base.feature +24 -0
- data/spec/acceptance/text_editor/check.feature +20 -0
- data/spec/acceptance/text_editor/load.feature +74 -0
- data/spec/acceptance/text_editor/save.feature +31 -0
- data/spec/controllers/editor_controller_spec.rb +2 -63
- data/spec/controllers/source_codes_controller_spec.rb +296 -0
- data/spec/models/source_code_spec.rb +44 -0
- data/spec/spec_helper.rb +123 -65
- data/spec/steps/ace_steps.rb +60 -0
- data/spec/steps/global_variable.rb +39 -0
- data/spec/steps/text_editor_steps.rb +160 -0
- data/spec/support/capybara.rb +17 -0
- metadata +49 -19
- data/spec/acceptance/editor.feature +0 -68
- data/spec/steps/editor_steps.rb +0 -123
@@ -0,0 +1,44 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
describe SourceCode, 'Rubyのソースコードを表現するモデル' do
|
5
|
+
describe '#check_syntax', 'シンタックスをチェックする' do
|
6
|
+
let(:source_code) {
|
7
|
+
SourceCode.new(data: data)
|
8
|
+
}
|
9
|
+
|
10
|
+
subject { source_code.check_syntax }
|
11
|
+
|
12
|
+
context 'シンタックスが正しい場合' do
|
13
|
+
let(:data) { 'puts "Hello, World!"' }
|
14
|
+
|
15
|
+
it { should be_empty }
|
16
|
+
end
|
17
|
+
|
18
|
+
context 'シンタックスが正しくない場合' do
|
19
|
+
let(:data) { 'puts Hello, World!"' }
|
20
|
+
|
21
|
+
it { should_not be_empty }
|
22
|
+
it {
|
23
|
+
should include(row: 1, column: 19,
|
24
|
+
message: 'syntax error, unexpected tSTRING_BEG,' \
|
25
|
+
" expecting keyword_do or '{' or '('")
|
26
|
+
}
|
27
|
+
it {
|
28
|
+
should include(row: 1, column: 0,
|
29
|
+
message: 'unterminated string meets end of file')
|
30
|
+
}
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
describe '#digest', 'プログラムのハッシュ値を計算する' do
|
35
|
+
let(:data) { 'puts "Hello, World!"' }
|
36
|
+
let(:source_code) {
|
37
|
+
SourceCode.new(data: data)
|
38
|
+
}
|
39
|
+
|
40
|
+
subject { source_code.digest }
|
41
|
+
|
42
|
+
it { should eq(Digest::SHA256.hexdigest(data)) }
|
43
|
+
end
|
44
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,70 +1,128 @@
|
|
1
|
-
#
|
2
|
-
|
3
|
-
require
|
4
|
-
|
5
|
-
require '
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
#
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
#
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
require 'rubygems'
|
3
|
+
require 'spork'
|
4
|
+
# uncomment the following line to use spork with the debugger
|
5
|
+
# require 'spork/ext/ruby-debug'
|
6
|
+
|
7
|
+
Spork.prefork do
|
8
|
+
# Loading more in this block will cause your tests to run faster. However,
|
9
|
+
# if you change any configuration or code from libraries loaded here, you'll
|
10
|
+
# need to restart spork for it take effect.
|
11
|
+
|
12
|
+
ENV['RAILS_ENV'] ||= 'test'
|
13
|
+
require File.expand_path('../../config/environment', __FILE__)
|
14
|
+
require 'rspec/rails'
|
15
|
+
require 'rspec/autorun'
|
16
|
+
require 'capybara/dsl'
|
17
|
+
require 'capybara/rspec'
|
18
|
+
require 'capybara/poltergeist'
|
19
|
+
require 'turnip'
|
20
|
+
require 'turnip/capybara'
|
21
|
+
require 'simplecov' if ENV['COVERAGE'] || ENV['COVERALLS']
|
22
|
+
|
23
|
+
# Requires supporting ruby files with custom matchers and macros, etc,
|
24
|
+
# in spec/support/ and its subdirectories.
|
25
|
+
Dir[Rails.root.join('spec/support/**/*.rb')].each { |f| require f }
|
26
|
+
|
27
|
+
load 'spec/steps/global_variable.rb', true
|
28
|
+
Dir.glob('spec/steps/**/*_steps.rb') { |f| load f, true }
|
29
|
+
|
30
|
+
# Checks for pending migrations before tests are run.
|
31
|
+
# If you are not using ActiveRecord, you can remove this line.
|
32
|
+
ActiveRecord::Migration.check_pending! if defined?(ActiveRecord::Migration)
|
33
|
+
|
34
|
+
RSpec.configure do |config|
|
35
|
+
# ## Mock Framework
|
36
|
+
#
|
37
|
+
# If you prefer to use mocha, flexmock or RR, uncomment the
|
38
|
+
# appropriate line:
|
39
|
+
#
|
40
|
+
# config.mock_with :mocha
|
41
|
+
# config.mock_with :flexmock
|
42
|
+
# config.mock_with :rr
|
43
|
+
|
44
|
+
# Remove this line if you're not using ActiveRecord or
|
45
|
+
# ActiveRecord fixtures
|
46
|
+
config.fixture_path = "#{::Rails.root}/spec/fixtures"
|
47
|
+
|
48
|
+
# If you're not using ActiveRecord, or you'd prefer not to run each of your
|
49
|
+
# examples within a transaction, remove the following line or assign false
|
50
|
+
# instead of true.
|
51
|
+
config.use_transactional_fixtures = true
|
52
|
+
|
53
|
+
# If true, the base class of anonymous controllers will be inferred
|
54
|
+
# automatically. This will be the default behavior in future versions of
|
55
|
+
# rspec-rails.
|
56
|
+
config.infer_base_class_for_anonymous_controllers = false
|
57
|
+
|
58
|
+
# Run specs in random order to surface order dependencies. If you find an
|
59
|
+
# order dependency and want to debug it, you can fix the order by providing
|
60
|
+
# the seed, which is printed after each run.
|
61
|
+
# --seed 1234
|
62
|
+
config.order = 'random'
|
63
|
+
|
64
|
+
twb = (ENV['TARGET_WEB_BROWZER'] || ENV['TWB']).try(:downcase)
|
65
|
+
case twb
|
66
|
+
when 'firefox', 'ie', 'chrome'
|
67
|
+
Capybara.register_driver :selenium do |app|
|
68
|
+
opts = { browser: twb.to_sym }
|
69
|
+
|
70
|
+
dir = downloads_dir.to_s
|
71
|
+
dir.gsub!(File::SEPARATOR, File::ALT_SEPARATOR) if windows?
|
72
|
+
case twb
|
73
|
+
when 'firefox'
|
74
|
+
opts[:profile] = profile = Selenium::WebDriver::Firefox::Profile.new
|
75
|
+
profile['browser.download.folderList'] = 2 # custom location
|
76
|
+
profile['browser.download.dir'] = dir
|
77
|
+
profile['browser.helperApps.neverAsk.saveToDisk'] = 'text/plain'
|
78
|
+
when 'ie'
|
79
|
+
opts[:introduce_flakiness_by_ignoring_security_domains] = true
|
80
|
+
when 'chrome'
|
81
|
+
FileUtils.mkdir_p(dir)
|
82
|
+
opts[:prefs] = {
|
83
|
+
download: {
|
84
|
+
prompt_for_download: false,
|
85
|
+
default_directory: dir,
|
86
|
+
directory_upgrade: true,
|
87
|
+
}
|
88
|
+
}
|
89
|
+
|
90
|
+
opts[:switches] =
|
91
|
+
%w(
|
92
|
+
--ignore-certificate-errors
|
93
|
+
--disable-popup-blocking
|
94
|
+
--disable-translate
|
95
|
+
)
|
96
|
+
end
|
97
|
+
|
98
|
+
Capybara::Selenium::Driver.new(app, opts)
|
99
|
+
end
|
100
|
+
Capybara.javascript_driver = :selenium
|
101
|
+
else
|
102
|
+
Capybara.javascript_driver = :poltergeist
|
58
103
|
end
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
104
|
+
|
105
|
+
config.include JsonSpec::Helpers
|
106
|
+
|
107
|
+
config.after(javascript: true) do
|
108
|
+
page.execute_script('window.onbeforeunload = null')
|
109
|
+
if selenium?
|
110
|
+
FileUtils.rm_rf(downloads_dir)
|
111
|
+
end
|
63
112
|
end
|
64
|
-
Capybara.javascript_driver = :selenium_chrome
|
65
|
-
else
|
66
|
-
Capybara.javascript_driver = :poltergeist
|
67
113
|
end
|
114
|
+
end
|
115
|
+
|
116
|
+
Spork.each_run do
|
117
|
+
# This code will be run each time you run your specs.
|
68
118
|
|
69
|
-
|
119
|
+
# http://penguinlab.jp/blog/post/2256# より
|
120
|
+
if Spork.using_spork?
|
121
|
+
# app 下のファイル / locale / routes をリロード
|
122
|
+
# railties-3.2.3/lib/rails/application/finisher.rb あたりを参考に
|
123
|
+
Rails.application.reloaders.each { |reloader| reloader.execute_if_updated }
|
124
|
+
|
125
|
+
# machinist gem を利用してる場合、blueprints を再度読み直す
|
126
|
+
# load "#{File.dirname(__FILE__)}/support/blueprints.rb"
|
127
|
+
end
|
70
128
|
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
text_editor = 'テキストエディタ'
|
4
|
+
|
5
|
+
step 'テキストエディタにフォーカスがあること' do
|
6
|
+
expect(page.evaluate_script(<<-JS)).to be_true
|
7
|
+
$('#{NAME_INFO[text_editor][:selector]} textarea.ace_text-input').get(0) ==
|
8
|
+
document.activeElement
|
9
|
+
JS
|
10
|
+
end
|
11
|
+
|
12
|
+
step 'テキストエディタの :row 行目の :column 文字目にカーソルがあること' do |row, column|
|
13
|
+
get_cursor_position_js =
|
14
|
+
"ace.edit('#{NAME_INFO[text_editor][:id]}').getCursorPosition()"
|
15
|
+
expect(page.evaluate_script("#{get_cursor_position_js}.row")).to eq(row.to_i)
|
16
|
+
expect(page.evaluate_script("#{get_cursor_position_js}.column"))
|
17
|
+
.to eq(column.to_i)
|
18
|
+
end
|
19
|
+
|
20
|
+
step 'テキストエディタに :program を入力済みである' do |program|
|
21
|
+
send 'テキストエディタにプログラムを入力済みである:', program
|
22
|
+
end
|
23
|
+
|
24
|
+
step 'テキストエディタにプログラムを入力済みである:' do |program|
|
25
|
+
page.execute_script(<<-JS)
|
26
|
+
ace.edit('#{NAME_INFO[text_editor][:id]}')
|
27
|
+
.getSession()
|
28
|
+
.getDocument()
|
29
|
+
.setValue('#{program.gsub(/'/, "\\\\'")}')
|
30
|
+
JS
|
31
|
+
end
|
32
|
+
|
33
|
+
step 'テキストエディタに :filename を読み込むこと' do |filename|
|
34
|
+
js = <<-JS
|
35
|
+
ace.edit('#{NAME_INFO[text_editor][:id]}')
|
36
|
+
.getSession()
|
37
|
+
.getDocument()
|
38
|
+
.getValue()
|
39
|
+
JS
|
40
|
+
path = Pathname(fixture_path).join(filename)
|
41
|
+
expect(page.evaluate_script(js)).to eq(path.read)
|
42
|
+
end
|
43
|
+
|
44
|
+
step 'テキストエディタのプログラムは以下であること:' do |program|
|
45
|
+
expect(page.evaluate_script(<<-JS)).to eq(program)
|
46
|
+
ace.edit('#{NAME_INFO[text_editor][:id]}')
|
47
|
+
.getSession()
|
48
|
+
.getDocument()
|
49
|
+
.getValue()
|
50
|
+
JS
|
51
|
+
end
|
52
|
+
|
53
|
+
step 'テキストエディタのプログラムは :program であること' do |program|
|
54
|
+
expect(page.evaluate_script(<<-JS)).to eq(program)
|
55
|
+
ace.edit('#{NAME_INFO[text_editor][:id]}')
|
56
|
+
.getSession()
|
57
|
+
.getDocument()
|
58
|
+
.getValue()
|
59
|
+
JS
|
60
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
::NAME_INFO = {
|
4
|
+
'トップページ' => {
|
5
|
+
path: '/',
|
6
|
+
},
|
7
|
+
'エディタ' => {
|
8
|
+
path: '/',
|
9
|
+
},
|
10
|
+
|
11
|
+
'Rubyタブ' => {
|
12
|
+
id: 'ruby-tab',
|
13
|
+
selector: '#ruby-tab',
|
14
|
+
},
|
15
|
+
'テキストエディタ' => {
|
16
|
+
id: 'text-editor',
|
17
|
+
selector: '#text-editor',
|
18
|
+
},
|
19
|
+
'プログラム名の入力欄' => {
|
20
|
+
id: 'filename',
|
21
|
+
selector: '#filename',
|
22
|
+
},
|
23
|
+
'チェックボタン' => {
|
24
|
+
id: 'check-button',
|
25
|
+
selector: '#check-button',
|
26
|
+
},
|
27
|
+
'セーブボタン' => {
|
28
|
+
id: 'save-button',
|
29
|
+
selector: '#save-button',
|
30
|
+
},
|
31
|
+
'ロードボタン' => {
|
32
|
+
id: 'load-button',
|
33
|
+
selector: '#load-button',
|
34
|
+
},
|
35
|
+
'メッセージ' => {
|
36
|
+
id: 'messages',
|
37
|
+
selector: '#messages',
|
38
|
+
},
|
39
|
+
}
|
@@ -0,0 +1,160 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
step ':name にアクセスする' do |name|
|
4
|
+
visit NAME_INFO[name][:path]
|
5
|
+
|
6
|
+
if poltergeist?
|
7
|
+
page.execute_script(<<-JS)
|
8
|
+
if (window.confirmMsg == undefined) {
|
9
|
+
window.confirmMsg = null;
|
10
|
+
window.confirm = function(msg) {
|
11
|
+
window.confirmMsg = msg;
|
12
|
+
return true;
|
13
|
+
}
|
14
|
+
}
|
15
|
+
JS
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
step ':name が表示されていること' do |name|
|
20
|
+
expect(page).to have_selector(NAME_INFO[name][:selector])
|
21
|
+
end
|
22
|
+
|
23
|
+
step ':name 画面を表示する' do |name|
|
24
|
+
send ':name にアクセスする', name
|
25
|
+
end
|
26
|
+
|
27
|
+
step 'プログラムの名前に :filename を指定する' do |filename|
|
28
|
+
fill_in('filename', with: filename)
|
29
|
+
end
|
30
|
+
|
31
|
+
step ':name をクリックする' do |name|
|
32
|
+
click_on(NAME_INFO[name][:id])
|
33
|
+
end
|
34
|
+
|
35
|
+
step 'ダウンロードが完了するまで待つ' do
|
36
|
+
start_time = Time.now
|
37
|
+
if poltergeist?
|
38
|
+
until page.response_headers['Content-Disposition'] ||
|
39
|
+
(start_time + 5.seconds) < Time.now
|
40
|
+
sleep 1
|
41
|
+
end
|
42
|
+
elsif selenium?
|
43
|
+
until downloads_dir.exist? || (start_time + 5.seconds) < Time.now
|
44
|
+
sleep 1
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
step ':filename をダウンロードすること' do |filename|
|
50
|
+
step 'ダウンロードが完了するまで待つ'
|
51
|
+
if poltergeist?
|
52
|
+
expect(page.response_headers['Content-Disposition'])
|
53
|
+
.to eq("attachment; filename=\"#{filename}\"")
|
54
|
+
expect(page.response_headers['Content-Type'])
|
55
|
+
.to eq('text/plain; charset=utf-8')
|
56
|
+
elsif selenium?
|
57
|
+
expect(downloads_dir.join(filename)).to be_exist
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
step 'ダウンロードしないこと' do
|
62
|
+
if poltergeist?
|
63
|
+
expect(page.response_headers['Content-Disposition']).to be_nil
|
64
|
+
elsif selenium?
|
65
|
+
expect(downloads_dir).not_to be_exist
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
step ':name にフォーカスがあること' do |name|
|
70
|
+
# HACK: 現在のPhantomJSでは$(':focus')は動作しない
|
71
|
+
# https://github.com/netzpirat/guard-jasmine/issues/48
|
72
|
+
expect(page.evaluate_script(<<-JS)).to be_true
|
73
|
+
$('#{NAME_INFO[name][:selector]}').get(0) == document.activeElement
|
74
|
+
JS
|
75
|
+
end
|
76
|
+
|
77
|
+
step ':filename をロードする' do |filename|
|
78
|
+
# HACK: input#load-file[type="file"]は非表示要素であるため、.show()し
|
79
|
+
# ないと見つけられずattach_fileが失敗する
|
80
|
+
page.execute_script("$('#load-file').show()")
|
81
|
+
|
82
|
+
path = Pathname(fixture_path).join(filename).to_s
|
83
|
+
path.gsub!(File::SEPARATOR, File::ALT_SEPARATOR) if windows?
|
84
|
+
attach_file('load-file', path)
|
85
|
+
end
|
86
|
+
|
87
|
+
step 'JavaScriptによるリクエストが終わるまで待つ' do
|
88
|
+
start_time = Time.now
|
89
|
+
until page.evaluate_script('jQuery.isReady && jQuery.active == 0') ||
|
90
|
+
(start_time + 5.seconds) < Time.now
|
91
|
+
sleep 1
|
92
|
+
end
|
93
|
+
end
|
94
|
+
step ':name は :value であること' do |name, value|
|
95
|
+
expect(page.evaluate_script(<<-JS)).to eq(value)
|
96
|
+
$('#{NAME_INFO[name][:selector]}').val()
|
97
|
+
JS
|
98
|
+
end
|
99
|
+
|
100
|
+
step ':name に :message を含むこと' do |name, message|
|
101
|
+
expect(page.find(NAME_INFO[name][:selector])).to have_content(message)
|
102
|
+
end
|
103
|
+
|
104
|
+
step ':name に :message を含まないこと' do |name, message|
|
105
|
+
expect(page.find(NAME_INFO[name][:selector])).to have_no_content(message)
|
106
|
+
end
|
107
|
+
|
108
|
+
step 'ページをリロードする' do
|
109
|
+
begin
|
110
|
+
step '"エディタ" 画面を表示する'
|
111
|
+
rescue Capybara::Poltergeist::TimeoutError => e
|
112
|
+
Rails.logger.debug("#{e.class.name}: #{e.message}")
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
step '警告ダイアログの :name ボタンをクリックする' do |name|
|
117
|
+
case name
|
118
|
+
when 'dismiss'
|
119
|
+
page.driver.browser.switch_to.alert.dismiss if selenium?
|
120
|
+
else
|
121
|
+
page.driver.browser.switch_to.alert.accept if selenium?
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
step '確認メッセージ :message を表示すること' do |message|
|
126
|
+
if poltergeist?
|
127
|
+
actual = page.evaluate_script('window.confirmMsg')
|
128
|
+
page.execute_script('window.confirmMsg = null')
|
129
|
+
expect(actual).to eq(message)
|
130
|
+
elsif selenium?
|
131
|
+
expect(page.driver.browser.switch_to.alert.text).to eq(message)
|
132
|
+
page.driver.browser.switch_to.alert.dismiss
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
step '確認メッセージを表示しないこと' do
|
137
|
+
if poltergeist?
|
138
|
+
actual = page.evaluate_script('window.confirmMsg')
|
139
|
+
page.execute_script('window.confirmMsg = null')
|
140
|
+
expect(actual).to be_nil
|
141
|
+
elsif selenium?
|
142
|
+
expect {
|
143
|
+
page.driver.browser.switch_to.alert
|
144
|
+
}.to raise_exception(Selenium::WebDriver::Error::NoAlertPresentError)
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
step '実際にはファイルをロードしないようにしておく' do
|
149
|
+
if selenium?
|
150
|
+
page.execute_script("$('#load-button').off('click')")
|
151
|
+
page.execute_script(<<-JS)
|
152
|
+
$('#load-button').click(function(e) {
|
153
|
+
e.preventDefault();
|
154
|
+
if (changed) {
|
155
|
+
confirm('まだセーブしていないのでロードするとプログラムが消えてしまうよ!それでもロードしますか?');
|
156
|
+
}
|
157
|
+
})
|
158
|
+
JS
|
159
|
+
end
|
160
|
+
end
|