Skip to content
This repository has been archived by the owner on Oct 23, 2022. It is now read-only.

Commit

Permalink
first version.
Browse files Browse the repository at this point in the history
  • Loading branch information
sosodev committed Dec 27, 2019
0 parents commit 2fd84fd
Show file tree
Hide file tree
Showing 18 changed files with 368 additions and 0 deletions.
8 changes: 8 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/.bundle/
/.yardoc
/_yardoc/
/coverage/
/doc/
/pkg/
/spec/reports/
/tmp/
3 changes: 3 additions & 0 deletions .idea/.gitignore

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 7 additions & 0 deletions .idea/.rakeTasks

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 13 additions & 0 deletions .idea/kinchan.iml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 7 additions & 0 deletions .idea/misc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions .idea/modules.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions .idea/vcs.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 7 additions & 0 deletions .rakeTasks
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<Settings><!--This file was automatically generated by Ruby plugin.
You are allowed to:
1. Remove rake task
2. Add existing rake tasks
To add existing rake tasks automatically delete this file and reload the project.
--><RakeGroup description="" fullCmd="" taksId="rake"><RakeTask description="Build kinchan-0.1.0.gem into the pkg directory" fullCmd="build" taksId="build" /><RakeTask description="Remove any temporary products" fullCmd="clean" taksId="clean" /><RakeTask description="Remove any generated files" fullCmd="clobber" taksId="clobber" /><RakeTask description="Build and install kinchan-0.1.0.gem into system gems" fullCmd="install" taksId="install" /><RakeGroup description="" fullCmd="" taksId="install"><RakeTask description="Build and install kinchan-0.1.0.gem into system gems without network access" fullCmd="install:local" taksId="local" /></RakeGroup><RakeTask description="Create tag v0.1.0 and build and push kinchan-0.1.0.gem to TODO: Set to 'http://mygemserver.com'" fullCmd="release[remote]" taksId="release[remote]" /><RakeTask description="" fullCmd="default" taksId="default" /><RakeTask description="" fullCmd="release" taksId="release" /><RakeGroup description="" fullCmd="" taksId="release"><RakeTask description="" fullCmd="release:guard_clean" taksId="guard_clean" /><RakeTask description="" fullCmd="release:rubygem_push" taksId="rubygem_push" /><RakeTask description="" fullCmd="release:source_control_push" taksId="source_control_push" /></RakeGroup></RakeGroup></Settings>
6 changes: 6 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
source "https://rubygems.org"

# Specify your gem's dependencies in kinchan.gemspec
gemspec

gem "rake", "~> 12.0"
27 changes: 27 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
PATH
remote: .
specs:
kinchan (0.1.0)
require_all (~> 3.0.0)
selenium-webdriver (~> 3.142.6)

GEM
remote: https://rubygems.org/
specs:
childprocess (3.0.0)
rake (12.3.2)
require_all (3.0.0)
rubyzip (2.0.0)
selenium-webdriver (3.142.6)
childprocess (>= 0.5, < 4.0)
rubyzip (>= 1.2.2)

PLATFORMS
ruby

DEPENDENCIES
kinchan!
rake (~> 12.0)

BUNDLED WITH
2.1.2
21 changes: 21 additions & 0 deletions LICENSE.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
The MIT License (MIT)

Copyright (c) 2019 Kyle McGough

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
130 changes: 130 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
# [Kinchan](https://itazuranakiss.fandom.com/wiki/Kinnosuke_Ikezawa)
## Composable browser automation for Ruby.

### Requirements

* Ruby
* Bundler

### Getting Started

Create a new directory for your Kinchan project

`mkdir kinchan_project && cd kinchan_project`

Create the tasks directory where you'll store your Kinchan tasks

`mkdir tasks`

Initialize bundler

`bundle init`

Add the Kinchan gem to your bundle

`bundle add kinchan`

Now that we've got the structure the rest of the readme will teach you how to create, compose, and run Kinchan tasks 👽

### Creating a Task

In your tasks directory create a Ruby file with any name

e.g. `touch ruby_reddit.rb`

In your task's Ruby file you'll need to `require 'kinchan'`

and then define your task as a class that inherits from `Kinchan::Task`

so far your file should look a little something like this
```ruby
require 'kinchan'

class VisitRubysReddit < Kinchan::Task
end
```

All Kinchan tasks require an execute method that takes a single parameter (the selenium browser object) like so

```ruby
require 'kinchan'

class VisitRubyReddit < Kinchan::Task
def execute(browser)
browser.navigate.to 'https://old.reddit.com/r/ruby'
end
end
```

That's all it takes to create a basic task! If we run it we'll see a browser process start and navigate to the Ruby subreddit. For a full description of the
browser API check out the [wiki page](https://github.com/SeleniumHQ/selenium/wiki/Ruby-Bindings) for Ruby Selenium (they call it a "driver").

### Running a Task

Create a Ruby file in the root level of your Kinchan project and require your task

Create a new instance of the task and call `run`

e.g.

```ruby
require_relative 'tasks/ruby_reddit'

VisitRubyReddit.new.run
```

That's all it takes to run a task. Kinchan handles the rest.

### Passing Data to a Task

A task's initialize function can accept options, just don't forget to call super

e.g.

```ruby
class Search < Kinchan::Task
def initialize(**options)
super
@query = options[:query]
end

def execute(browser)
browser.navigate.to 'https://www.google.com/search?q=#{CGI.escape(@query)}'
end
end
```

### Composing Tasks

Tasks can call any number of other tasks either before or after they execute, and their dependencies
will have their dependencies ran and so on

This is done by specifying dependencies with a task's `@before_tasks` or `@after_tasks` in their initialize method

e.g.

```ruby
class PrintFirstResult < Kinchan::Task
def initialize(**options)
super
@before_tasks << { task: :search, options: options }
# specify that the search task should run, with the same options, before running this task
end

def execute(browser)
puts browser.execute_script "return document.querySelector('.srg a').innerText"
end
end
```

Task's do not need to be in the same scope, as long as the task exists Kinchan will find and run it when appropriate

### Setting Selenium Browser Options

before running your task you can modify the selenium browser options like so

```ruby
Kinchan::Task.browser = :chrome
Kinchan::Task.browser_options = Selenium::WebDriver::Chrome::Options.new
Kinchan::Task.browser_options.add_argument('--headless')
```
2 changes: 2 additions & 0 deletions Rakefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
require "bundler/gem_tasks"
task :default => :spec
14 changes: 14 additions & 0 deletions bin/console
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#!/usr/bin/env ruby

require "bundler/setup"
require "kinchan"

# You can add fixtures and/or initialization code here to make experimenting
# with your gem easier. You can also use a different console, if you like.

# (If you use this, don't forget to add pry to your Gemfile!)
# require "pry"
# Pry.start

require "irb"
IRB.start(__FILE__)
8 changes: 8 additions & 0 deletions bin/setup
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#!/usr/bin/env bash
set -euo pipefail
IFS=$'\n\t'
set -vx

bundle install

# Do any other automated setup that you need to do here
30 changes: 30 additions & 0 deletions kinchan.gemspec
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
require_relative 'lib/kinchan/version'

Gem::Specification.new do |spec|
spec.name = "kinchan"
spec.version = Kinchan::VERSION
spec.authors = ["Kyle McGough"]
spec.email = ["[email protected]"]

spec.summary = %q{Composable browser automation with Ruby.}
spec.description = %q{Composable browser automation with Ruby. Create, compose, and run tasks that automate the browser with Selenium.}
spec.homepage = "https://github.com/sosodev/kinchan"
spec.license = "MIT"
spec.required_ruby_version = Gem::Requirement.new(">= 2.3.0")

spec.metadata["homepage_uri"] = spec.homepage
spec.metadata["source_code_uri"] = spec.homepage
spec.metadata["changelog_uri"] = spec.homepage

# Specify which files should be added to the gem when it is released.
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
end
spec.bindir = "exe"
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
spec.require_paths = ["lib"]

spec.add_runtime_dependency 'selenium-webdriver', ['~> 3.142.6']
spec.add_runtime_dependency 'require_all', ['~> 3.0.0']
end
66 changes: 66 additions & 0 deletions lib/kinchan.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# frozen_string_literal: true

require 'kinchan/version'
require 'selenium-webdriver'
require 'require_all'

module Kinchan
class Error < StandardError; end

class Task
singleton_class.send(:attr_accessor, :browser)
singleton_class.send(:attr_accessor, :browser_options)
singleton_class.send(:attr_reader, :descendants)
@descendants = []
@browser = :chrome
@browser_options = nil
@@browser_webdriver = nil

def initialize(**options)
@before_tasks = []
@after_tasks = []
@options = options
end

def self.inherited(subclass)
Task.descendants << subclass
end

def self.find_task(task_symbol)
Task.descendants.select { |task| task.name.split('::').last.downcase == task_symbol.to_s.downcase }[0]
end

def self.restart_browser
unless @@browser_webdriver.nil?
@@browser_webdriver.close
@@browser_webdriver = Selenium::WebDriver.for Task.browser
end
end

def execute(browser); end

def run
if @@browser_webdriver.nil?
if Task.browser_options.nil?
@@browser_webdriver = Selenium::WebDriver.for Task.browser
else
@@browser_webdriver = Selenium::WebDriver.for(Task.browser, options: Task.browser_options)
end
end

@before_tasks.each do |task_hash|
task = Task.find_task(task_hash[:task])
task.new(**task_hash[:options]).public_send('run') unless task.nil?
end

execute(@@browser_webdriver)

@after_tasks.each do |task_hash|
task = Task.find_task(task_hash[:task])
task.new(**task_hash[:options]).public_send('run') unless task.nil?
end
end
end
end

require_all 'tasks'
5 changes: 5 additions & 0 deletions lib/kinchan/version.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# frozen_string_literal: true

module Kinchan
VERSION = '0.1.0'
end

0 comments on commit 2fd84fd

Please sign in to comment.