diff --git a/gems/rubocop-canvas/config/default.yml b/gems/rubocop-canvas/config/default.yml index 8865e846afe..2a1a02ebc12 100644 --- a/gems/rubocop-canvas/config/default.yml +++ b/gems/rubocop-canvas/config/default.yml @@ -80,6 +80,14 @@ Specs/NoBeforeOnceStubs: - "**/spec/**/*.rb" - "**/spec_canvas/**/*.rb" +Specs/NoDisableImplicitWait: + Enabled: true + Include: + - "**/spec/**/*.rb" + - "**/spec_canvas/**/*.rb" + Exclude: + - "**/spec/selenium/test_setup/**/*.rb" + Specs/NoExecuteScript: Enabled: true Include: @@ -94,12 +102,28 @@ Specs/NoNoSuchElementError: - "**/spec/**/*.rb" - "**/spec_canvas/**/*.rb" +Specs/NoSeleniumWebDriverWait: + Enabled: true + Include: + - "**/spec/**/*.rb" + - "**/spec_canvas/**/*.rb" + Exclude: + - "**/spec/selenium/test_setup/**/*.rb" + Specs/NoStrftime: Enabled: true Include: - "**/spec/**/*.rb" - "**/spec_canvas/**/*.rb" +Specs/NoWaitForNoSuchElement: + Enabled: true + Include: + - "**/spec/**/*.rb" + - "**/spec_canvas/**/*.rb" + Exclude: + - "**/spec/selenium/test_setup/**/*.rb" + Specs/PreferFOverFj: Enabled: true Include: diff --git a/gems/rubocop-canvas/lib/rubocop_canvas.rb b/gems/rubocop-canvas/lib/rubocop_canvas.rb index a8cc9175a1f..710faa4befc 100644 --- a/gems/rubocop-canvas/lib/rubocop_canvas.rb +++ b/gems/rubocop-canvas/lib/rubocop_canvas.rb @@ -26,10 +26,13 @@ require 'rubocop_canvas/cops/rails/smart_time_zone' ## specs require 'rubocop_canvas/cops/specs/no_before_all' require 'rubocop_canvas/cops/specs/no_before_once_stubs' +require 'rubocop_canvas/cops/specs/no_disable_implicit_wait.rb' require 'rubocop_canvas/cops/specs/ensure_spec_extension' require 'rubocop_canvas/cops/specs/no_execute_script' require 'rubocop_canvas/cops/specs/no_no_such_element_error' +require 'rubocop_canvas/cops/specs/no_selenium_web_driver_wait.rb' require 'rubocop_canvas/cops/specs/no_strftime' +require 'rubocop_canvas/cops/specs/no_wait_for_no_such_element' require 'rubocop_canvas/cops/specs/prefer_f_over_fj' require 'rubocop_canvas/cops/specs/scope_helper_modules' require 'rubocop_canvas/cops/specs/deterministic_described_classes' diff --git a/gems/rubocop-canvas/lib/rubocop_canvas/cops/specs/no_disable_implicit_wait.rb b/gems/rubocop-canvas/lib/rubocop_canvas/cops/specs/no_disable_implicit_wait.rb new file mode 100644 index 00000000000..460ba8a2614 --- /dev/null +++ b/gems/rubocop-canvas/lib/rubocop_canvas/cops/specs/no_disable_implicit_wait.rb @@ -0,0 +1,19 @@ +module RuboCop + module Cop + module Specs + class NoDisableImplicitWait < Cop + MSG = "Avoid using disable_implicit_wait.\n" \ + "Look through custom_selenium_rspec_matchers.rb" \ + " and custom_wait_methods.rb.".freeze + + METHOD = :disable_implicit_wait + + def on_send(node) + _receiver, method_name, *_args = *node + return unless method_name == METHOD + add_offense node, :expression, MSG, :warning + end + end + end + end +end diff --git a/gems/rubocop-canvas/lib/rubocop_canvas/cops/specs/no_selenium_web_driver_wait.rb b/gems/rubocop-canvas/lib/rubocop_canvas/cops/specs/no_selenium_web_driver_wait.rb new file mode 100644 index 00000000000..89c10f5316b --- /dev/null +++ b/gems/rubocop-canvas/lib/rubocop_canvas/cops/specs/no_selenium_web_driver_wait.rb @@ -0,0 +1,34 @@ +module RuboCop + module Cop + module Specs + class NoSeleniumWebDriverWait < Cop + MSG = "Avoid using Selenium::WebDriver::Wait.\n" \ + "Our finders (f/fj and ff/ffj) will wait up to the implicit wait" \ + " (just like find_element, etc), and will raise a" \ + " Selenium::WebDriver::Error::NoSuchElementError" \ + " (just like find_element, etc).\n" \ + "Look through custom_selenium_rspec_matchers.rb" \ + " and custom_wait_methods.rb.".freeze + + BAD_CONST = "Selenium::WebDriver::Wait".freeze + BAD_CONST_MATCHER = BAD_CONST.split("::") + .map { |name| ":#{name})" } + .join(" ") + + # (const + # (const + # (const nil :Selenium) :WebDriver) :Wait) + def_node_matcher :bad_const?, <<-PATTERN + (const + (const + (const nil #{BAD_CONST_MATCHER} + PATTERN + + def on_const(node) + return unless bad_const?(node) + add_offense node, :expression, MSG, :warning + end + end + end + end +end diff --git a/gems/rubocop-canvas/lib/rubocop_canvas/cops/specs/no_wait_for_no_such_element.rb b/gems/rubocop-canvas/lib/rubocop_canvas/cops/specs/no_wait_for_no_such_element.rb new file mode 100644 index 00000000000..cdf63f09bb3 --- /dev/null +++ b/gems/rubocop-canvas/lib/rubocop_canvas/cops/specs/no_wait_for_no_such_element.rb @@ -0,0 +1,19 @@ +module RuboCop + module Cop + module Specs + class NoWaitForNoSuchElement < Cop + MSG = "Avoid using wait_for_no_such_element. Instead, use"\ + " not_to contain_css/contain_link.\n"\ + "e.g. expect(f('#courses')).not_to contain_css('#course_123')".freeze + + METHOD = :wait_for_no_such_element + + def on_send(node) + _receiver, method_name, *_args = *node + return unless method_name == METHOD + add_offense node, :expression, MSG, :warning + end + end + end + end +end diff --git a/gems/rubocop-canvas/spec/rubocop/cop/specs/no_disable_implicit_wait_spec.rb b/gems/rubocop-canvas/spec/rubocop/cop/specs/no_disable_implicit_wait_spec.rb new file mode 100644 index 00000000000..03c83d3a2ba --- /dev/null +++ b/gems/rubocop-canvas/spec/rubocop/cop/specs/no_disable_implicit_wait_spec.rb @@ -0,0 +1,27 @@ +describe RuboCop::Cop::Specs::NoDisableImplicitWait do + subject(:cop) { described_class.new } + + it 'disallows disable_implicit_wait' do + inspect_source(cop, %{ + describe "sis imports ui" do + it 'should properly show sis stickiness options' do + expect(ff('.fc-view-container .icon-calendar-month')).to have_size(1) + + # Calendar currently has post loading javascript that places the calendar event + # In the correct place, however we don't have a wait_ajax_animation that waits + # Long enough for this spec to pass given that we drag too soon causing it to fail + disable_implicit_wait do + keep_trying_until(10) do + # Verify Event now ends at assignment start time + 30 minutes + drag_and_drop_element(f('.fc-end-resizer'), f('.icon-assignment')) + expect(event1.reload.end_at).to eql(midnight + 12.hours + 30.minutes) + end + end + end + end + }) + expect(cop.offenses.size).to eq(1) + expect(cop.messages.first).to match(/disable_implicit_wait/) + expect(cop.offenses.first.severity.name).to eq(:warning) + end +end diff --git a/gems/rubocop-canvas/spec/rubocop/cop/specs/no_selenium_web_driver_wait_spec.rb b/gems/rubocop-canvas/spec/rubocop/cop/specs/no_selenium_web_driver_wait_spec.rb new file mode 100644 index 00000000000..448c307758e --- /dev/null +++ b/gems/rubocop-canvas/spec/rubocop/cop/specs/no_selenium_web_driver_wait_spec.rb @@ -0,0 +1,22 @@ +describe RuboCop::Cop::Specs::NoSeleniumWebDriverWait do + subject(:cop) { described_class.new } + let(:msg_regex) { /Avoid using Selenium::WebDriver::Wait/ } + + it 'disallows Selenium::WebDriver::Wait' do + inspect_source(cop, %{ + describe "breaks all the things" do + wait = Selenium::WebDriver::Wait.new(timeout: 5) + wait.until do + el = f('.self_enrollment_message') + el.present? && + el.text != nil && + el.text != "" + end + expect(f('.self_enrollment_message')).not_to include_text('self_enrollment_code') + end + }) + expect(cop.offenses.size).to eq(1) + expect(cop.messages.first).to match(msg_regex) + expect(cop.offenses.first.severity.name).to eq(:warning) + end +end diff --git a/gems/rubocop-canvas/spec/rubocop/cop/specs/no_wait_for_no_such_element_spec.rb b/gems/rubocop-canvas/spec/rubocop/cop/specs/no_wait_for_no_such_element_spec.rb new file mode 100644 index 00000000000..40f614319f5 --- /dev/null +++ b/gems/rubocop-canvas/spec/rubocop/cop/specs/no_wait_for_no_such_element_spec.rb @@ -0,0 +1,18 @@ +describe RuboCop::Cop::Specs::NoWaitForNoSuchElement do + subject(:cop) { described_class.new } + + it 'disallows wait_for_no_such_element' do + inspect_source(cop, %{ + describe "sis imports ui" do + it 'should properly show sis stickiness options' do + wait_for_no_such_element(method: :contain_css) do + f("#studentAvatar", f('#courses')) + end + end + end + }) + expect(cop.offenses.size).to eq(1) + expect(cop.messages.first).to match(/wait_for_no_such_element/) + expect(cop.offenses.first.severity.name).to eq(:warning) + end +end