testai_classifier 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: c3ea7ee65e1ed0cd0115c7f376bdd3d1246408649e40eddd778fe8c6b876cdeb
4
+ data.tar.gz: 605c5c9f9a448cc28e0b5818722da66976f062c81aa835d1b4728dcad070514e
5
+ SHA512:
6
+ metadata.gz: 146b9275636a14fb6a4b0c2598d3a6dba53eca1a8ddf1dd810aaf993d71a624b8c085245e1dbb819288b76f127a5bd8e8a4f09b9300de3516f669074b2e5a271
7
+ data.tar.gz: 47e9a22da0eb1442e770395a02d7b4308d1d8d7195287a5f93272233a4518cea42682e825956924c886ebd52d1352232ebe3c0d995ba2fda07e6b4cdff6710df
@@ -0,0 +1,27 @@
1
+ # Generated by the protocol buffer compiler. DO NOT EDIT!
2
+ # source: classifier.proto
3
+
4
+ require 'google/protobuf'
5
+
6
+ Google::Protobuf::DescriptorPool.generated_pool.build do
7
+ add_file("classifier.proto", :syntax => :proto3) do
8
+ add_message "ElementClassificationRequest" do
9
+ optional :labelHint, :string, 1
10
+ map :elementImages, :string, :bytes, 2
11
+ optional :confidenceThreshold, :double, 3
12
+ optional :allowWeakerMatches, :bool, 4
13
+ end
14
+ add_message "ElementClassificationResult" do
15
+ optional :label, :string, 1
16
+ optional :confidence, :double, 2
17
+ optional :confidenceForHint, :double, 3
18
+ end
19
+ add_message "ClassifiedElements" do
20
+ map :classifications, :string, :message, 1, "ElementClassificationResult"
21
+ end
22
+ end
23
+ end
24
+
25
+ ElementClassificationRequest = Google::Protobuf::DescriptorPool.generated_pool.lookup("ElementClassificationRequest").msgclass
26
+ ElementClassificationResult = Google::Protobuf::DescriptorPool.generated_pool.lookup("ElementClassificationResult").msgclass
27
+ ClassifiedElements = Google::Protobuf::DescriptorPool.generated_pool.lookup("ClassifiedElements").msgclass
@@ -0,0 +1,20 @@
1
+ # Generated by the protocol buffer compiler. DO NOT EDIT!
2
+ # Source: classifier.proto for package ''
3
+
4
+ require 'grpc'
5
+ require_relative 'classifier_pb'
6
+
7
+ module Classifier
8
+ class Service
9
+
10
+ include GRPC::GenericService
11
+
12
+ self.marshal_class_method = :encode
13
+ self.unmarshal_class_method = :decode
14
+ self.service_name = 'Classifier'
15
+
16
+ rpc :ClassifyElements, ElementClassificationRequest, ClassifiedElements
17
+ end
18
+
19
+ Stub = Service.rpc_stub_class
20
+ end
@@ -0,0 +1,14 @@
1
+ module WebDriverExtensions
2
+ module Element
3
+ def screenshot()
4
+ data = bridge.take_element_screenshot @id
5
+ data.unpack1 'm'
6
+ end
7
+ end
8
+
9
+ module Bridge
10
+ def take_element_screenshot(element)
11
+ execute :take_element_screenshot, {id: element}
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,53 @@
1
+ require 'selenium-webdriver'
2
+ require 'testai_classifier/classifier_services_pb'
3
+ require 'testai_classifier/extensions'
4
+
5
+ # Selenium Ruby client doesn't currently implement the 'take element
6
+ # screenshot' command, so we have to patch it in
7
+ Selenium::WebDriver::Element.include WebDriverExtensions::Element
8
+ Selenium::WebDriver::Remote::Bridge.include WebDriverExtensions::Bridge
9
+
10
+ DEF_CONFIDENCE = 0.2
11
+ QUERY = "//body//*[not(self::script) and not(self::style) and not(child::*)]"
12
+
13
+ class ClassifierClient
14
+ def initialize(host, port)
15
+ @stub = Classifier::Stub.new("#{host}:#{port}", :this_channel_is_insecure)
16
+ end
17
+
18
+ def classify_images(label, element_images, confidence=DEF_CONFIDENCE,
19
+ allow_weaker_matches=false)
20
+ ecr = ElementClassificationRequest
21
+ req = ecr.new(labelHint: label,
22
+ elementImages: element_images,
23
+ confidenceThreshold: confidence,
24
+ allowWeakerMatches: allow_weaker_matches)
25
+ resp = @stub.classify_elements(req)
26
+ ret = {}
27
+ resp.classifications.each do |id, cls|
28
+ ret[id] = {
29
+ :label => cls.label,
30
+ :confidence => cls.confidence,
31
+ :confidence_for_hint => cls.confidenceForHint
32
+ }
33
+ end
34
+ return ret
35
+ end
36
+
37
+ def find_elements_matching_label(driver, label, confidence=DEF_CONFIDENCE, allow_weaker_matches=false)
38
+ els = driver.find_elements(:xpath, QUERY)
39
+ element_images = {}
40
+ els.each do |el|
41
+ begin
42
+ element_images[el.ref] = el.screenshot
43
+ rescue
44
+ end
45
+ end
46
+ if element_images.size < 1
47
+ raise "Could not find any screenshots for leaf node elements"
48
+ end
49
+ matched = self.classify_images(label, element_images, confidence,
50
+ allow_weaker_matches)
51
+ return els.select {|el| matched.has_key? el.ref}
52
+ end
53
+ end
metadata ADDED
@@ -0,0 +1,104 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: testai_classifier
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Jonathan Lipps
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2019-11-29 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: grpc
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.25'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.25'
27
+ - !ruby/object:Gem::Dependency
28
+ name: selenium-webdriver
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '3.142'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '3.142'
41
+ - !ruby/object:Gem::Dependency
42
+ name: grpc-tools
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '1.25'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '1.25'
55
+ - !ruby/object:Gem::Dependency
56
+ name: minitest
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '5.13'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '5.13'
69
+ description: The test.ai image classification RPC server can listen for requests from
70
+ this client in order to classify images and even use a Selenium client object to
71
+ find elements in a webpage matching a certain label
72
+ email: jlipps@cloudgrey.io
73
+ executables: []
74
+ extensions: []
75
+ extra_rdoc_files: []
76
+ files:
77
+ - lib/testai_classifier.rb
78
+ - lib/testai_classifier/classifier_pb.rb
79
+ - lib/testai_classifier/classifier_services_pb.rb
80
+ - lib/testai_classifier/extensions.rb
81
+ homepage: https://github.com/testdotai/appium-classifier-plugin
82
+ licenses:
83
+ - Apache-2.0
84
+ metadata: {}
85
+ post_install_message:
86
+ rdoc_options: []
87
+ require_paths:
88
+ - lib
89
+ required_ruby_version: !ruby/object:Gem::Requirement
90
+ requirements:
91
+ - - ">="
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
94
+ required_rubygems_version: !ruby/object:Gem::Requirement
95
+ requirements:
96
+ - - ">="
97
+ - !ruby/object:Gem::Version
98
+ version: '0'
99
+ requirements: []
100
+ rubygems_version: 3.0.3
101
+ signing_key:
102
+ specification_version: 4
103
+ summary: A client to the Test.ai + Appium Classifier server
104
+ test_files: []