| 348 |
348 |
end
|
| 349 |
349 |
end
|
| 350 |
350 |
end
|
|
351 |
|
|
352 |
def test_undo_after_autofill_reverts_everything
|
|
353 |
with_settings :text_formatting => 'textile' do
|
|
354 |
visit '/projects/ecookbook/issues/new'
|
|
355 |
|
|
356 |
within('form#issue-form') do
|
|
357 |
find('#issue_description').send_keys('* First item')
|
|
358 |
find('#issue_description').send_keys(:enter)
|
|
359 |
find('#issue_description').send_keys('Second item')
|
|
360 |
assert_equal("* First item\n* Second item", find('#issue_description').value)
|
|
361 |
|
|
362 |
assert_equal('', undo_states(find('#issue_description')).last)
|
|
363 |
end
|
|
364 |
end
|
|
365 |
end
|
|
366 |
|
|
367 |
def test_undo_after_marker_removal_restores_the_marker
|
|
368 |
with_settings :text_formatting => 'textile' do
|
|
369 |
visit '/projects/ecookbook/issues/new'
|
|
370 |
|
|
371 |
within('form#issue-form') do
|
|
372 |
find('#issue_description').send_keys('* First item')
|
|
373 |
find('#issue_description').send_keys(:enter)
|
|
374 |
find('#issue_description').send_keys(:enter)
|
|
375 |
assert_equal("* First item\n", find('#issue_description').value)
|
|
376 |
|
|
377 |
states = undo_states(find('#issue_description'))
|
|
378 |
assert_includes(states, "* First item\n* ")
|
|
379 |
assert_equal('', states.last)
|
|
380 |
end
|
|
381 |
end
|
|
382 |
end
|
|
383 |
|
|
384 |
def test_autofill_falls_back_when_exec_command_is_unusable
|
|
385 |
stubs = {
|
|
386 |
'missing' => 'document.execCommand = undefined;',
|
|
387 |
'refusing' => 'document.execCommand = function() { return false; };',
|
|
388 |
'throwing' => 'document.execCommand = function() { throw new Error("removed"); };'
|
|
389 |
}
|
|
390 |
|
|
391 |
with_settings :text_formatting => 'textile' do
|
|
392 |
stubs.each do |name, stub|
|
|
393 |
visit '/projects/ecookbook/issues/new'
|
|
394 |
page.execute_script(stub)
|
|
395 |
|
|
396 |
find('#issue_description').send_keys('* First item')
|
|
397 |
find('#issue_description').send_keys(:enter)
|
|
398 |
assert_equal("* First item\n* ", find('#issue_description').value,
|
|
399 |
"marker was not inserted with a #{name} execCommand")
|
|
400 |
|
|
401 |
find('#issue_description').send_keys(:enter)
|
|
402 |
assert_equal("* First item\n", find('#issue_description').value,
|
|
403 |
"marker was not removed with a #{name} execCommand")
|
|
404 |
end
|
|
405 |
end
|
|
406 |
end
|
|
407 |
|
|
408 |
private
|
|
409 |
|
|
410 |
# The browser applies an undo asynchronously and groups entries its own way,
|
|
411 |
# so wait for each press to land and collect every value seen.
|
|
412 |
def undo_states(field, max: 20)
|
|
413 |
keys = [RUBY_PLATFORM.include?('darwin') ? :command : :control, 'z']
|
|
414 |
states = [field.value]
|
|
415 |
max.times do
|
|
416 |
field.send_keys(keys)
|
|
417 |
deadline = Process.clock_gettime(Process::CLOCK_MONOTONIC) + Capybara.default_max_wait_time
|
|
418 |
sleep 0.05 while field.value == states.last &&
|
|
419 |
Process.clock_gettime(Process::CLOCK_MONOTONIC) < deadline
|
|
420 |
break if field.value == states.last
|
|
421 |
|
|
422 |
states << field.value
|
|
423 |
end
|
|
424 |
states
|
|
425 |
end
|
| 351 |
426 |
end
|