More Exception handling

This commit is contained in:
Daniel Ziltener 2022-04-27 01:10:51 +02:00
parent 28fecd077d
commit b894fdf757
10 changed files with 153 additions and 13 deletions

View File

@ -23,6 +23,18 @@ WebDriverTest >> tearDown [
super tearDown.
]
{ #category : #tests }
WebDriverTest >> testAttributeValue [
| element |
element := webdriver
url: 'http://info.cern.ch';
findElement: 'a' using: WDLocationStrategy cssSelector.
self
assert: (webdriver attribute: 'href' from: element)
equals: 'http://info.cern.ch/hypertext/WWW/TheProject.html'
]
{ #category : #tests }
WebDriverTest >> testFindElementInvalidCSSSelector [
self
@ -51,3 +63,8 @@ WebDriverTest >> testFindElementsValid [
findElements: '.badge-link__bullet' using: WDLocationStrategy cssSelector.
self assert: result size equals: 3.
]
{ #category : #tests }
WebDriverTest >> testGetTitle [
self assert: (webdriver url: 'https://cern.ch'; title) equals: 'Home | CERN'
]

View File

@ -0,0 +1,33 @@
Class {
#name : #WDElement,
#superclass : #String,
#instVars : [
'selector',
'locationStrategy'
],
#category : #WebDriver
}
{ #category : #accessing }
WDElement >> locationStrategy [
^ locationStrategy
]
{ #category : #accessing }
WDElement >> locationStrategy: anObject [
locationStrategy := anObject
]
{ #category : #accessing }
WDElement >> selector [
^ selector
]
{ #category : #accessing }
WDElement >> selector: anObject [
selector := anObject
]

View File

@ -0,0 +1,8 @@
"
The Element Click command could not be completed because the element receiving the events is obscuring the element that was requested clicked.
"
Class {
#name : #WDElementClickIntercepted,
#superclass : #WDException,
#category : #WebDriver
}

View File

@ -0,0 +1,8 @@
"
A command could not be completed because the element is not pointer- or keyboard interactable.
"
Class {
#name : #WDElementNotInteractable,
#superclass : #WDException,
#category : #WebDriver
}

View File

@ -0,0 +1,55 @@
"
I am the parent class of all WebDriver exceptions.
"
Class {
#name : #WDException,
#superclass : #Exception,
#instVars : [
'stacktrace',
'data'
],
#category : #WebDriver
}
{ #category : #'as yet unclassified' }
WDException class >> raise: errDict [
"Initializes and populates the appropriate exception class."
| error message stacktrace data |
error := errDict at: #error.
message := errDict at: #message.
stacktrace := errDict at: #stacktrace.
data := errDict at: #data ifAbsent: nil.
(error = 'element click intercepted')
ifTrue: [ ^ WDElementClickIntercepted new data: data; stacktrace: stacktrace; signal: message ].
(error = 'element not interactable')
ifTrue: [ ^ WDElementNotInteractable new data: data; stacktrace: stacktrace; signal: message ].
(error = 'insecure certificate')
ifTrue: [ ^ WDInsecureCertificate new data: data; stacktrace: stacktrace; signal: message ].
(error = 'invalid selector')
ifTrue: [ ^ WDInvalidSelector new data: data; stacktrace: stacktrace; signal: message ].
]
{ #category : #accessing }
WDException >> data [
^ data
]
{ #category : #accessing }
WDException >> data: anObject [
data := anObject
]
{ #category : #accessing }
WDException >> stacktrace [
^ stacktrace
]
{ #category : #accessing }
WDException >> stacktrace: anObject [
stacktrace := anObject
]

View File

@ -0,0 +1,5 @@
Class {
#name : #WDInsecureCertificate,
#superclass : #WDException,
#category : #WebDriver
}

View File

@ -1,5 +1,8 @@
"
Argument was an invalid selector.
"
Class {
#name : #WDInvalidSelector,
#superclass : #Exception,
#superclass : #WDException,
#category : #WebDriver
}

View File

@ -1,3 +1,6 @@
"
I provide class methods returning character codes for non-printable characters.
"
Class {
#name : #WDKeys,
#superclass : #Object,

View File

@ -1,3 +1,6 @@
"
I provide location strategy values used in messages like `WebDriver>>findElement:using:`.
"
Class {
#name : #WDLocationStrategy,
#superclass : #Object,

View File

@ -23,6 +23,15 @@ WebDriver class >> geckodriver [
port: 4444.
]
{ #category : #accessing }
WebDriver >> attribute: attr from: element [
^ (self send: { }
to: 'session/',sessionId,'/element/',element,'/attribute/',attr
using: #GET)
at: #value.
]
{ #category : #navigation }
WebDriver >> back [
self send: { } to: 'session/',sessionId,'/back' using: #POST.
@ -55,8 +64,8 @@ WebDriver >> findElement: elemSelector using: locStrategy [
using: #POST)
at: #value.
(reply at: #error ifPresent: [ true ] ifAbsent: [ false ])
ifTrue: [ ^ WDInvalidSelector new signal: (reply at: #message) ]
ifFalse: [ ^ reply values first ]
ifTrue: [ ^ WDException raise: reply ]
ifFalse: [ ^ (WDElement fromString: reply values first) ]
]
{ #category : #accessing }
@ -67,8 +76,8 @@ WebDriver >> findElements: elemSelector using: locStrategy [
using: #POST)
at: #value.
(reply isArray)
ifTrue: [ ^ reply collect: [ :elem | elem values first ] ]
ifFalse: [ ^ WDInvalidSelector new signal: (reply at: #message) ]
ifTrue: [ ^ reply collect: [ :elem | WDElement fromString: elem values first ] ]
ifFalse: [ ^ WDException raise: reply ]
]
{ #category : #navigation }
@ -76,12 +85,6 @@ WebDriver >> forward [
self send: { } to: 'session/',sessionId,'/forward' using: #POST.
]
{ #category : #initialization }
WebDriver >> initialize: srv port: portnum [
server := srv.
port := portnum.
]
{ #category : #navigation }
WebDriver >> refresh [
self send: { } to: 'session/',sessionId,'/refresh' using: #POST.
@ -100,6 +103,8 @@ WebDriver >> send: dict to: url using: method [
method: method;
contentReader: [ :entity |
result := (NeoJSONReader on: (entity contents) readStream) propertyNamesAsSymbols: true; next.
"(result at: #error ifPresent: [ true ] ifAbsent: [ false ])
ifTrue: [ result := WDException raise: result ]"
];
execute.
^result.
@ -108,7 +113,8 @@ WebDriver >> send: dict to: url using: method [
{ #category : #accessing }
WebDriver >> session [
"Initializes a new WebDriver session."
sessionId := (self send: {} to: 'session' using: #POST) at: #value at: #sessionId.
sessionId
ifNil: [ sessionId := (self send: {} to: 'session' using: #POST) at: #value at: #sessionId ].
^sessionId.
]
@ -125,7 +131,6 @@ WebDriver >> title [
{ #category : #'text input' }
WebDriver >> type: text into: element [
self send: { #text -> text } to: 'session/',sessionId,'/element/',element,'/value' using: #POST.
]
{ #category : #navigation }