testai_classifier 1.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 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: []