kobot 1.2.3 → 2.0.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3eba14b1e3b076a368dd700c2ac46a9db4fd13bf57a58e29797de7db7eb16fc3
4
- data.tar.gz: 1926333cefbaf4272ae117cc7afb12284ed85d6ff41aa96a02094904599b5312
3
+ metadata.gz: 0e2452d15afce1b0ec273b240ab062cc526adedcf7f11ecaf98e7cbe3590d393
4
+ data.tar.gz: 16f3f7fefbf4f30c621148841ba93aa57b8859cc5adb092edad02b3e6970e95c
5
5
  SHA512:
6
- metadata.gz: '08ad9cb2d55c2931a34ed4243884a7e16c189d1d914e5aa935cfd4d32fc3d3d7567cdaecdb53de54e980e84ec4c6e696761b7f9b15fb65e3a0eef11f829370e5'
7
- data.tar.gz: f8662e41fe53d35df04b1b530f946621330124684d6bd955e6b18e53830efaef74c22db66818a8a3958aa8a4745b4d37090419f538962c3a4876e8dbb9b6c1d7
6
+ metadata.gz: 4ec4604ff3d7486b48bc574f3130f2856787d6cb46644ba11cf1832569590dfe5a6159518a8474390a28500f77cd506da58531981df855db8e0d220627bb6486
7
+ data.tar.gz: 6f57f5fdf3e1f5186ca8ae60b6a482d555ca5a6e23004fec8f5bef324942001f7008fddfc96e93151c8ad88a9d17a99440bfef912540c2715a622433ea67b1a1
data/CHANGELOG.md CHANGED
@@ -22,3 +22,18 @@
22
22
  ### v1.2.3
23
23
  - Improved validation logic to skip running due to weekend or intentional skips
24
24
  - Refactored engine by reducing methods length based on reports by Rubocop
25
+
26
+ ### v1.2.4
27
+ - Changed to use boolean values for validation instead of raising exceptions
28
+
29
+ ### v1.2.5
30
+ - Added I18n support for both English and Japanese KOT UI
31
+
32
+ ### v1.3.0
33
+ - Added config option (-a, --auto-skip-without) to enable automatic skipping based on schedule
34
+ - Replaced deprecated options with capabilities option in Selenium driver initialization
35
+ - Refactored scattered attr_accessors and reduced instance variables count reported by Rubocop
36
+
37
+ ### v2.0.0
38
+ - Added -a, --auto-skip flag to support the enabling and disabling of auto-skipping feature
39
+ - Renamed the schedule config option from -a, --auto-skip-without to -w, --auto-skip-without
data/README.md CHANGED
@@ -62,6 +62,10 @@ Usage: kobot [options]
62
62
  -s, --skip [D1,D2,D3] Specify dates to skip clock in/out with date format YYYY-MM-DD and
63
63
  multiple values separated by comma, such as: 2020-05-01,2020-12-31;
64
64
  weekends and public holidays in Japan will be skipped by default
65
+ -a, --auto-skip Enable auto-skipping by reading schedule from the Time Card page
66
+ -w [SCHEDULE], Skip today if the provided text is not contained in the schedule
67
+ --auto-skip-without column on the Time Card page of KOT; by default 裁量労働 is used;
68
+ effective only if --auto-skip is passed to enable auto-skipping.
65
69
  -t, --to [TO] Email address to send notification to; by default it is sent to
66
70
  the same self email account used in SMTP config as the sender
67
71
  -n, --notify Enable email notification
data/lib/kobot/config.rb CHANGED
@@ -8,24 +8,22 @@ module Kobot
8
8
  attr_accessor :clock,
9
9
  :loglevel,
10
10
  :skip,
11
+ :auto_skip,
12
+ :auto_skip_without,
11
13
  :dryrun,
12
- :force
13
-
14
- attr_accessor :kot_url,
14
+ :force,
15
+ :kot_url,
15
16
  :kot_timezone_offset,
16
- :kot_date_format
17
-
18
- attr_accessor :gmail_notify_enabled,
17
+ :kot_date_format,
18
+ :gmail_notify_enabled,
19
19
  :gmail_notify_subject,
20
20
  :gmail_notify_to,
21
21
  :gmail_smtp_address,
22
- :gmail_smtp_port
23
-
24
- attr_accessor :browser_headless,
22
+ :gmail_smtp_port,
23
+ :browser_headless,
25
24
  :browser_geolocation,
26
- :browser_wait_timeout
27
-
28
- attr_accessor :credentials_file
25
+ :browser_wait_timeout,
26
+ :credentials_file
29
27
 
30
28
  def configure
31
29
  yield self
data/lib/kobot/engine.rb CHANGED
@@ -14,7 +14,7 @@ module Kobot
14
14
 
15
15
  # The entrance where the whole flow starts.
16
16
  #
17
- # It exits early if today is weekend or treated as holiday by
17
+ # It exits early if today is weekend or marked as to skip by
18
18
  # the #{Config.skip} specified from command line option --skip.
19
19
  #
20
20
  # Unexpected behavior such as record appearing as holiday on
@@ -24,7 +24,8 @@ module Kobot
24
24
  # System errors or any unknown exceptions occurred if any are
25
25
  # to be popped up and should be handled by the outside caller.
26
26
  def start
27
- validate_today!
27
+ return unless should_run_today?
28
+
28
29
  launch_browser
29
30
  login
30
31
  read_today_record
@@ -35,8 +36,6 @@ module Kobot
35
36
  clock_out!
36
37
  end
37
38
  logout
38
- rescue KotSkip => e
39
- Kobot.logger.warn(e.message)
40
39
  rescue KotRecordError => e
41
40
  Kobot.logger.warn(e.message)
42
41
  Mailer.send(clock_notify_message(status: e.message))
@@ -60,13 +59,16 @@ module Kobot
60
59
 
61
60
  private
62
61
 
63
- def validate_today!
64
- raise KotSkip, "Today=#{@today} is skipped as per: --skip=#{Config.skip}" if skip?
65
-
66
- return unless weekend?
67
- raise KotSkip, "Today=#{@today} is weekend" unless Config.force
62
+ def should_run_today?
63
+ if skip?
64
+ Kobot.logger.warn("Today=#{@today} is skipped as per: --skip=#{Config.skip}")
65
+ return false
66
+ end
67
+ return true unless weekend?
68
68
 
69
- Kobot.logger.info("[Force] should have exited: today=#{@today} is weekend")
69
+ Kobot.logger.info("[Force] should have exited: today=#{@today} is weekend") if Config.force
70
+ Kobot.logger.warn("Today=#{@today} is weekend") unless Config.force
71
+ Config.force
70
72
  end
71
73
 
72
74
  def launch_browser
@@ -79,7 +81,10 @@ module Kobot
79
81
  }
80
82
  options = Selenium::WebDriver::Chrome::Options.new(prefs: prefs)
81
83
  options.headless! if Config.browser_headless
82
- @browser = Selenium::WebDriver.for(:chrome, options: options)
84
+ caps = [
85
+ options
86
+ ]
87
+ @browser = Selenium::WebDriver.for(:chrome, capabilities: caps)
83
88
  @wait = Selenium::WebDriver::Wait.new(timeout: Config.browser_wait_timeout)
84
89
  Kobot.logger.info('Launch browser successful')
85
90
  end
@@ -95,6 +100,12 @@ module Kobot
95
100
  Kobot.logger.info("Navigate to: #{@top_url}")
96
101
  @browser.get @top_url
97
102
  @wait.until { @browser.find_element(id: 'modal_window') }
103
+ modal_title_element = @wait.until { @browser.find_element(css: '.modal-title') }
104
+ @selector = if modal_title_element.text.downcase.include? 'password'
105
+ Selector.en
106
+ else
107
+ Selector.ja
108
+ end
98
109
  Kobot.logger.info "Page title: #{@browser.title}"
99
110
  Kobot.logger.debug do
100
111
  "Login with id=#{Credential.kot_id} and password=#{Credential.kot_password}"
@@ -104,10 +115,14 @@ module Kobot
104
115
  @browser.find_element(css: 'div.btn-control-message').click
105
116
 
106
117
  Kobot.logger.info 'Login successful'
107
- @wait.until { @browser.find_element(id: 'notification_content').text.include?('データを取得しました') }
118
+ @wait.until do
119
+ @browser.find_element(id: 'notification_content').text.include?(@selector.login_success_notification_text)
120
+ end
108
121
  if Config.browser_geolocation
109
122
  begin
110
- @wait.until { @browser.find_element(id: 'location_area').text.include?('位置情報取得済み') }
123
+ @wait.until do
124
+ @browser.find_element(id: 'location_area').text.include?(@selector.location_area_notification_text)
125
+ end
111
126
  rescue StandardError => e
112
127
  Kobot.logger.warn "Get geolocation failed: #{e.message}"
113
128
  end
@@ -117,21 +132,21 @@ module Kobot
117
132
 
118
133
  def logout
119
134
  if @browser.current_url.include? 'admin'
120
- Kobot.logger.info('Logout from タイムカード page')
135
+ Kobot.logger.info('Logout from Time Card (タイムカード) page')
121
136
  @browser.find_element(css: 'div.htBlock-header_logoutButton').click
122
137
  else
123
- Kobot.logger.info('Logout from Myレコーダー page')
138
+ Kobot.logger.info('Logout from My Recorder (Myレコーダー) page')
124
139
  @wait.until { @browser.find_element(id: 'menu_icon') }.click
125
- @wait.until { @browser.find_element(link: 'ログアウト') }.click
140
+ @wait.until { @browser.find_element(link: @selector.logout_menu_link_text) }.click
126
141
  @browser.switch_to.alert.accept
127
142
  end
128
143
  Kobot.logger.info 'Logout successful'
129
144
  end
130
145
 
131
146
  def read_today_record
132
- Kobot.logger.info('Navigate to タイムカード page')
147
+ Kobot.logger.info('Navigate to Time Card (タイムカード) page')
133
148
  @wait.until { @browser.find_element(id: 'menu_icon') }.click
134
- @wait.until { @browser.find_element(link: 'タイムカード') }.click
149
+ @wait.until { @browser.find_element(link: @selector.time_card_menu_link_text) }.click
135
150
 
136
151
  time_table = @wait.until { @browser.find_element(css: 'div.htBlock-adjastableTableF_inner > table') }
137
152
  time_table.find_elements(css: 'tbody > tr').each do |tr|
@@ -139,22 +154,24 @@ module Kobot
139
154
  next unless date_cell.text.include? @today
140
155
 
141
156
  Kobot.logger.info('Reading today record')
142
- @kot_today = date_cell.text
143
- @kot_today_css_class = date_cell.attribute('class')
144
- @kot_today_type = tr.find_element(css: 'td.work_day_type').text
145
- @kot_today_clock_in = tr.find_element(
157
+ @kot_data = {}
158
+ @kot_data[:today] = date_cell.text
159
+ @kot_data[:today_css_class] = date_cell.attribute('class')
160
+ @kot_data[:today_type] = tr.find_element(css: 'td.work_day_type').text
161
+ @kot_data[:today_schedule] = tr.find_element(css: 'td.schedule').text
162
+ @kot_data[:today_clock_in] = tr.find_element(
146
163
  css: 'td.start_end_timerecord[data-ht-sort-index="START_TIMERECORD"]'
147
164
  ).text
148
- @kot_today_clock_out = tr.find_element(
165
+ @kot_data[:today_clock_out] = tr.find_element(
149
166
  css: 'td.start_end_timerecord[data-ht-sort-index="END_TIMERECORD"]'
150
167
  ).text
151
168
  Kobot.logger.debug do
152
169
  {
153
- kot_toay: @kot_today,
154
- kot_today_css_class: @kot_today_css_class,
155
- kot_today_type: @kot_today_type,
156
- kot_today_clock_in: @kot_today_clock_in,
157
- kot_today_clock_out: @kot_today_clock_out
170
+ kot_toay: @kot_data[:today],
171
+ kot_today_css_class: @kot_data[:today_css_class],
172
+ kot_today_type: @kot_data[:today_type],
173
+ kot_today_clock_in: @kot_data[:today_clock_in],
174
+ kot_today_clock_out: @kot_data[:today_clock_out]
158
175
  }
159
176
  end
160
177
  break
@@ -162,60 +179,71 @@ module Kobot
162
179
  end
163
180
 
164
181
  def validate_today_record!
165
- raise KotRecordError, "Today=#{@today} is not found on kot" if @kot_today.strip.empty?
182
+ raise KotRecordError, "Today=#{@today} is not found on kot" if @kot_data[:today].strip.empty?
166
183
 
167
184
  if kot_weekend?
168
- raise KotRecordError, "Today=#{@today} is marked as weekend on kot: #{@kot_today}" unless Config.force
185
+ raise KotRecordError, "Today=#{@today} is marked as weekend: #{@kot_data[:today]}" unless Config.force
169
186
 
170
187
  Kobot.logger.info(
171
- "[Force] should have exited: today=#{@today} is marked as weekend on kot: #{@kot_today}"
188
+ "[Force] should have exited: today=#{@today} is marked as weekend: #{@kot_data[:today]}"
172
189
  )
173
190
  end
174
191
 
175
- return unless kot_public_holiday?
176
- raise KotRecordError, "Today=#{@today} is marked as public holiday on kot: #{@kot_today}" unless Config.force
192
+ if kot_public_holiday?
193
+ raise KotRecordError, "Today=#{@today} is marked as public holiday: #{@kot_data[:today]}" unless Config.force
177
194
 
178
- Kobot.logger.info(
179
- "[Force] should have exited: today=#{@today} is marked as public holiday on kot: #{@kot_today}"
180
- )
195
+ Kobot.logger.info(
196
+ "[Force] should have exited: today=#{@today} is marked as public holiday: #{@kot_data[:today]}"
197
+ )
198
+ end
199
+
200
+ return unless Config.auto_skip
201
+
202
+ if kot_non_work_schedule?
203
+ raise KotRecordError, "Today=#{@today} is non-work schedule: #{@kot_data[:today_schedule]}" unless Config.force
204
+
205
+ Kobot.logger.info(
206
+ "[Force] should have exited: today=#{@today} is non-work schedule: #{@kot_data[:today_schedule]}"
207
+ )
208
+ end
181
209
  end
182
210
 
183
211
  def clock_in!
184
212
  Kobot.logger.warn("Clock in during the afternoon: #{@now}") if @now.hour > 12
185
- if @kot_today_clock_in.strip.empty?
213
+ if @kot_data[:today_clock_in].strip.empty?
186
214
  click_clock_in_button
187
215
  return if Config.dryrun
188
216
 
189
217
  read_today_record
190
- raise KotClockInError, 'Clock in operation seems to have failed' if @kot_today_clock_in.strip.empty?
218
+ raise KotClockInError, 'Clock in operation seems to have failed' if @kot_data[:today_clock_in].strip.empty?
191
219
 
192
- Kobot.logger.info("Clock in successful: #{@kot_today_clock_in}")
220
+ Kobot.logger.info("Clock in successful: #{@kot_data[:today_clock_in]}")
193
221
  Mailer.send(clock_notify_message(clock: :in))
194
222
  else
195
- Kobot.logger.warn("Clock in done already: #{@kot_today_clock_in}")
223
+ Kobot.logger.warn("Clock in done already: #{@kot_data[:today_clock_in]}")
196
224
  end
197
225
  end
198
226
 
199
227
  def clock_out!
200
228
  Kobot.logger.warn("Clock out during the morning: #{@now}") if @now.hour <= 12
201
229
  unless Config.dryrun
202
- if @kot_today_clock_in.strip.empty?
230
+ if @kot_data[:today_clock_in].strip.empty?
203
231
  raise KotClockOutError,
204
- "!!!No clock in record for today=#{@kot_today}!!!"
232
+ "!!!No clock in record for today=#{@kot_data[:today]}!!!"
205
233
  end
206
234
  end
207
235
 
208
- if @kot_today_clock_out.strip.empty?
236
+ if @kot_data[:today_clock_out].strip.empty?
209
237
  click_clock_out_button
210
238
  return if Config.dryrun
211
239
 
212
240
  read_today_record
213
- raise KotClockOutError, 'Clock out operation seems to have failed' if @kot_today_clock_out.strip.empty?
241
+ raise KotClockOutError, 'Clock out operation seems to have failed' if @kot_data[:today_clock_out].strip.empty?
214
242
 
215
- Kobot.logger.info("Clock out successful: #{@kot_today_clock_out}")
243
+ Kobot.logger.info("Clock out successful: #{@kot_data[:today_clock_out]}")
216
244
  Mailer.send(clock_notify_message(clock: :out))
217
245
  else
218
- Kobot.logger.warn("Clock out done already: #{@kot_today_clock_out}")
246
+ Kobot.logger.warn("Clock out done already: #{@kot_data[:today_clock_out]}")
219
247
  end
220
248
  end
221
249
 
@@ -224,9 +252,9 @@ module Kobot
224
252
  @browser.get @top_url
225
253
  clock_in_button = @wait.until { @browser.find_element(css: 'div.record-clock-in') }
226
254
  if Config.dryrun
227
- Kobot.logger.info('[Dryrun] clock in button (出勤) would have been clicked')
255
+ Kobot.logger.info('[Dryrun] Clock-in button (出勤) would have been clicked')
228
256
  else
229
- Kobot.logger.info('Clicking the clock in button (出勤)')
257
+ Kobot.logger.info('Clicking the Clock-in button (出勤)')
230
258
  clock_in_button.click
231
259
  end
232
260
  end
@@ -236,9 +264,9 @@ module Kobot
236
264
  @browser.get @top_url
237
265
  clock_out_button = @wait.until { @browser.find_element(css: 'div.record-clock-out') }
238
266
  if Config.dryrun
239
- Kobot.logger.info('[Dryrun] clock out button (退勤) would have been clicked')
267
+ Kobot.logger.info('[Dryrun] Clock-out button (退勤) would have been clicked')
240
268
  else
241
- Kobot.logger.info('Clicking the clock in button (退勤)')
269
+ Kobot.logger.info('Clicking the Clock-out button (退勤)')
242
270
  clock_out_button.click
243
271
  end
244
272
  end
@@ -255,18 +283,25 @@ module Kobot
255
283
  end
256
284
 
257
285
  def kot_weekend?
258
- %w[土 日].any? { |kanji| @kot_today&.include? kanji }
286
+ [
287
+ @selector.kot_date_saturday,
288
+ @selector.kot_date_sunday
289
+ ].any? { |weekend| @kot_data[:today]&.include? weekend }
290
+ end
291
+
292
+ def kot_non_work_schedule?
293
+ !@kot_data[:today_schedule]&.include?(Config.auto_skip_without)
259
294
  end
260
295
 
261
296
  def kot_public_holiday?
262
- return true if @kot_today_type&.include? '休日'
297
+ return true if @kot_data[:today_type]&.include? @selector.kot_workday_time_off_text
263
298
 
264
299
  kot_today_highlighted = %w[sunday saturday].any? do |css|
265
- @kot_today_css_class&.include? css
300
+ @kot_data[:today_css_class]&.include? css
266
301
  end
267
302
  if kot_today_highlighted
268
303
  Kobot.logger.warn(
269
- "Today=#{@kot_today} is highlighted (holiday) but not marked as 休日"
304
+ "Today=#{@kot_data[:today]} is highlighted (holiday) but not marked as #{@selector.kot_workday_time_off_text}"
270
305
  )
271
306
  end
272
307
  kot_today_highlighted
@@ -278,8 +313,8 @@ module Kobot
278
313
  "<b>Date:</b> #{@today}",
279
314
  "<b>Status:</b> <span style='color:#{color}'>#{status}</span>"
280
315
  ]
281
- message << "<b>Clock_in:</b> #{@kot_today_clock_in}" if clock
282
- message << "<b>Clock_out:</b> #{@kot_today_clock_out}" if clock == :out
316
+ message << "<b>Clock_in:</b> #{@kot_data[:today_clock_in]}" if clock
317
+ message << "<b>Clock_out:</b> #{@kot_data[:today_clock_out]}" if clock == :out
283
318
  message.join('<br>')
284
319
  end
285
320
  end
@@ -1,15 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Kobot
4
- class KotSkip < StandardError
5
- end
6
-
7
- class KotRecordError < StandardError
8
- end
9
-
10
- class KotClockInError < StandardError
11
- end
12
-
13
- class KotClockOutError < StandardError
14
- end
4
+ class KotRecordError < StandardError; end
5
+ class KotClockInError < StandardError; end
6
+ class KotClockOutError < StandardError; end
15
7
  end
data/lib/kobot/mailer.rb CHANGED
@@ -47,7 +47,7 @@ module Kobot
47
47
  To: <#{to}>
48
48
  MIME-Version: 1.0
49
49
  Content-type: text/html
50
- Subject: #{subject}
50
+ Subject: #{subject}
51
51
  Date: #{Time.now.getlocal(Config.kot_timezone_offset)}
52
52
 
53
53
  #{body}
data/lib/kobot/option.rb CHANGED
@@ -27,6 +27,17 @@ module Kobot
27
27
  options[:skip] = skip
28
28
  end
29
29
 
30
+ opt.on('-a', '--auto-skip', 'Enable auto-skipping by reading schedule from the Time Card page') do |auto_skip|
31
+ options[:auto_skip] = auto_skip
32
+ end
33
+
34
+ opt.on('-w', '--auto-skip-without [SCHEDULE]',
35
+ 'Skip today if the provided text is not contained in the schedule',
36
+ 'column on the Time Card page of KOT; by default 裁量労働 is used;',
37
+ 'effective only if --auto-skip is passed to enable auto-skipping.') do |schedule|
38
+ options[:auto_skip_without] = schedule
39
+ end
40
+
30
41
  opt.on('-t', '--to [TO]',
31
42
  'Email address to send notification to; by default it is sent to',
32
43
  'the same self email account used in SMTP config as the sender') do |to|
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Kobot
4
+ # The texts used in selectors to identify the elements on KOT UI.
5
+ class Selector
6
+ attr_accessor :login_success_notification_text,
7
+ :location_area_notification_text,
8
+ :time_card_menu_link_text,
9
+ :kot_date_saturday,
10
+ :kot_date_sunday,
11
+ :kot_workday_time_off_text,
12
+ :logout_menu_link_text
13
+
14
+ class << self
15
+ def en
16
+ selector = Selector.new
17
+ selector.login_success_notification_text = 'Data has been obtained'
18
+ selector.location_area_notification_text = 'Obtained location'
19
+ selector.time_card_menu_link_text = 'Time Card'
20
+ selector.kot_date_saturday = 'Sat'
21
+ selector.kot_date_sunday = 'Sun'
22
+ selector.kot_workday_time_off_text = 'time-off'
23
+ selector.logout_menu_link_text = 'Sign out'
24
+ selector
25
+ end
26
+
27
+ def ja
28
+ selector = Selector.new
29
+ selector.login_success_notification_text = 'データを取得しました'
30
+ selector.location_area_notification_text = '位置情報取得済み'
31
+ selector.time_card_menu_link_text = 'タイムカード'
32
+ selector.kot_date_saturday = '土'
33
+ selector.kot_date_sunday = '日'
34
+ selector.kot_workday_time_off_text = '休日'
35
+ selector.logout_menu_link_text = 'ログアウト'
36
+ selector
37
+ end
38
+ end
39
+ end
40
+ end
data/lib/kobot/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Kobot
4
- VERSION = '1.2.3'
4
+ VERSION = '2.0.0'
5
5
  end
data/lib/kobot.rb CHANGED
@@ -4,6 +4,7 @@ require 'kobot/version'
4
4
  require 'kobot/exception'
5
5
  require 'kobot/option'
6
6
  require 'kobot/config'
7
+ require 'kobot/selector'
7
8
  require 'kobot/credential'
8
9
  require 'kobot/logger'
9
10
  require 'kobot/mailer'
@@ -33,6 +34,8 @@ module Kobot
33
34
  config.dryrun = options[:dryrun]
34
35
  config.force = options[:force]
35
36
  config.skip = options[:skip] || []
37
+ config.auto_skip = options[:auto_skip]
38
+ config.auto_skip_without = options[:auto_skip_without] || '裁量労働'
36
39
 
37
40
  config.kot_url = 'https://s2.kingtime.jp/independent/recorder/personal/'
38
41
  config.kot_timezone_offset = '+09:00'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kobot
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.3
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andy Jiang
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-09-05 00:00:00.000000000 Z
11
+ date: 2021-12-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: webdrivers
@@ -83,6 +83,7 @@ files:
83
83
  - lib/kobot/logger.rb
84
84
  - lib/kobot/mailer.rb
85
85
  - lib/kobot/option.rb
86
+ - lib/kobot/selector.rb
86
87
  - lib/kobot/version.rb
87
88
  homepage: https://github.com/yuan-jiang/kobot
88
89
  licenses:
@@ -107,7 +108,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
107
108
  - !ruby/object:Gem::Version
108
109
  version: '0'
109
110
  requirements: []
110
- rubygems_version: 3.0.3
111
+ rubygems_version: 3.1.2
111
112
  signing_key:
112
113
  specification_version: 4
113
114
  summary: Kobot automates the clock in/out of KING OF TIME.