Improved exception handling
This commit is contained in:
parent
af10bbbae1
commit
c0dce773e9
|
@ -0,0 +1,13 @@
|
||||||
|
"
|
||||||
|
A command failed because the referenced shadow root is no longer attached to the DOM.
|
||||||
|
"
|
||||||
|
Class {
|
||||||
|
#name : #WDDetachedShadowRoot,
|
||||||
|
#superclass : #WDException,
|
||||||
|
#category : #'WebDriver-Exception'
|
||||||
|
}
|
||||||
|
|
||||||
|
{ #category : #testing }
|
||||||
|
WDDetachedShadowRoot class >> matchesErrorCode: errCode [
|
||||||
|
^ errCode = 'detached shadow root'
|
||||||
|
]
|
|
@ -4,5 +4,10 @@ The Element Click command could not be completed because the element receiving t
|
||||||
Class {
|
Class {
|
||||||
#name : #WDElementClickIntercepted,
|
#name : #WDElementClickIntercepted,
|
||||||
#superclass : #WDException,
|
#superclass : #WDException,
|
||||||
#category : #WebDriver
|
#category : #'WebDriver-Exception'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{ #category : #testing }
|
||||||
|
WDElementClickIntercepted class >> matchesErrorCode: errCode [
|
||||||
|
^ errCode = 'element click intercepted'
|
||||||
|
]
|
||||||
|
|
|
@ -4,5 +4,10 @@ A command could not be completed because the element is not pointer- or keyboard
|
||||||
Class {
|
Class {
|
||||||
#name : #WDElementNotInteractable,
|
#name : #WDElementNotInteractable,
|
||||||
#superclass : #WDException,
|
#superclass : #WDException,
|
||||||
#category : #WebDriver
|
#category : #'WebDriver-Exception'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{ #category : #testing }
|
||||||
|
WDElementNotInteractable class >> matchesErrorCode: errCode [
|
||||||
|
^ errCode = 'element not interactable'
|
||||||
|
]
|
||||||
|
|
|
@ -8,26 +8,32 @@ Class {
|
||||||
'stacktrace',
|
'stacktrace',
|
||||||
'data'
|
'data'
|
||||||
],
|
],
|
||||||
#category : #WebDriver
|
#category : #'WebDriver-Exception'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{ #category : #testing }
|
||||||
|
WDException class >> matchesErrorCode: errCode [
|
||||||
|
^ self subclassResponsibility.
|
||||||
|
]
|
||||||
|
|
||||||
{ #category : #signaling }
|
{ #category : #signaling }
|
||||||
WDException class >> raise: errDict [
|
WDException class >> raise: errDict [
|
||||||
|
|
||||||
"Initializes and populates the appropriate exception class."
|
"Initializes and populates the appropriate exception class."
|
||||||
| error message stacktrace data |
|
|
||||||
|
| errorClass error message stacktrace data |
|
||||||
error := errDict at: #error.
|
error := errDict at: #error.
|
||||||
message := errDict at: #message.
|
message := errDict at: #message.
|
||||||
stacktrace := errDict at: #stacktrace.
|
stacktrace := errDict at: #stacktrace.
|
||||||
data := errDict at: #data ifAbsent: nil.
|
data := errDict at: #data ifAbsent: nil.
|
||||||
(error = 'element click intercepted')
|
errorClass := self subclasses
|
||||||
ifTrue: [ ^ WDElementClickIntercepted new data: data; stacktrace: stacktrace; signal: message ].
|
detect: [ :operationClass |
|
||||||
(error = 'element not interactable')
|
operationClass matchesErrorCode: error ]
|
||||||
ifTrue: [ ^ WDElementNotInteractable new data: data; stacktrace: stacktrace; signal: message ].
|
ifNone: [ self ].
|
||||||
(error = 'insecure certificate')
|
^ errorClass new
|
||||||
ifTrue: [ ^ WDInsecureCertificate new data: data; stacktrace: stacktrace; signal: message ].
|
data: data;
|
||||||
(error = 'invalid selector')
|
stacktrace: stacktrace;
|
||||||
ifTrue: [ ^ WDInvalidSelector new data: data; stacktrace: stacktrace; signal: message ].
|
signal: message
|
||||||
|
|
||||||
]
|
]
|
||||||
|
|
||||||
{ #category : #accessing }
|
{ #category : #accessing }
|
||||||
|
|
|
@ -4,5 +4,10 @@ Navigation caused the user agent to hit a certificate warning, which is usually
|
||||||
Class {
|
Class {
|
||||||
#name : #WDInsecureCertificate,
|
#name : #WDInsecureCertificate,
|
||||||
#superclass : #WDException,
|
#superclass : #WDException,
|
||||||
#category : #WebDriver
|
#category : #'WebDriver-Exception'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{ #category : #testing }
|
||||||
|
WDInsecureCertificate class >> matchesErrorCode: errCode [
|
||||||
|
^ errCode = 'insecure certificate'
|
||||||
|
]
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
"
|
||||||
|
The arguments passed to a command are either invalid or malformed.
|
||||||
|
"
|
||||||
|
Class {
|
||||||
|
#name : #WDInvalidArgument,
|
||||||
|
#superclass : #WDException,
|
||||||
|
#category : #'WebDriver-Exception'
|
||||||
|
}
|
||||||
|
|
||||||
|
{ #category : #testing }
|
||||||
|
WDInvalidArgument class >> matchesErrorCode: errCode [
|
||||||
|
^ errCode = 'invalid argument'
|
||||||
|
]
|
|
@ -0,0 +1,13 @@
|
||||||
|
"
|
||||||
|
An illegal attempt was made to set a cookie under a different domain than the current page.
|
||||||
|
"
|
||||||
|
Class {
|
||||||
|
#name : #WDInvalidCookieDomain,
|
||||||
|
#superclass : #WDException,
|
||||||
|
#category : #'WebDriver-Exception'
|
||||||
|
}
|
||||||
|
|
||||||
|
{ #category : #testing }
|
||||||
|
WDInvalidCookieDomain class >> matchesErrorCode: errCode [
|
||||||
|
^ errCode = 'invalid cookie domain'
|
||||||
|
]
|
|
@ -0,0 +1,13 @@
|
||||||
|
"
|
||||||
|
A command could not be completed because the element is in an invalid state, e.g. attempting to clear an element that isn’t both editable and resettable.
|
||||||
|
"
|
||||||
|
Class {
|
||||||
|
#name : #WDInvalidElementState,
|
||||||
|
#superclass : #WDException,
|
||||||
|
#category : #'WebDriver-Exception'
|
||||||
|
}
|
||||||
|
|
||||||
|
{ #category : #testing }
|
||||||
|
WDInvalidElementState class >> matchesErrorCode: errCode [
|
||||||
|
^ errCode = 'invalid element state'
|
||||||
|
]
|
|
@ -4,5 +4,10 @@ Argument was an invalid selector.
|
||||||
Class {
|
Class {
|
||||||
#name : #WDInvalidSelector,
|
#name : #WDInvalidSelector,
|
||||||
#superclass : #WDException,
|
#superclass : #WDException,
|
||||||
#category : #WebDriver
|
#category : #'WebDriver-Exception'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{ #category : #testing }
|
||||||
|
WDInvalidSelector class >> matchesErrorCode: errCode [
|
||||||
|
^ errCode = 'invalid selector'
|
||||||
|
]
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
"
|
||||||
|
Occurs if the given session id is not in the list of active sessions, meaning the session either does not exist or that it’s not active.
|
||||||
|
"
|
||||||
|
Class {
|
||||||
|
#name : #WDInvalidSessionId,
|
||||||
|
#superclass : #WDException,
|
||||||
|
#category : #'WebDriver-Exception'
|
||||||
|
}
|
||||||
|
|
||||||
|
{ #category : #testing }
|
||||||
|
WDInvalidSessionId class >> matchesErrorCode: errCode [
|
||||||
|
^ errCode = 'invalid session id'
|
||||||
|
]
|
|
@ -0,0 +1,13 @@
|
||||||
|
"
|
||||||
|
An error occurred while executing JavaScript supplied by the user.
|
||||||
|
"
|
||||||
|
Class {
|
||||||
|
#name : #WDJavascriptError,
|
||||||
|
#superclass : #WDException,
|
||||||
|
#category : #'WebDriver-Exception'
|
||||||
|
}
|
||||||
|
|
||||||
|
{ #category : #testing }
|
||||||
|
WDJavascriptError class >> matchesErrorCode: errCode [
|
||||||
|
^ errCode = 'javascript error'
|
||||||
|
]
|
|
@ -0,0 +1,13 @@
|
||||||
|
"
|
||||||
|
The target for mouse interaction is not in the browser’s viewport and cannot be brought into that viewport.
|
||||||
|
"
|
||||||
|
Class {
|
||||||
|
#name : #WDMoveTargetOutOfBounds,
|
||||||
|
#superclass : #WDException,
|
||||||
|
#category : #'WebDriver-Exception'
|
||||||
|
}
|
||||||
|
|
||||||
|
{ #category : #testing }
|
||||||
|
WDMoveTargetOutOfBounds class >> matchesErrorCode: errCode [
|
||||||
|
^ errCode = 'move target out of bounds'
|
||||||
|
]
|
|
@ -0,0 +1,13 @@
|
||||||
|
"
|
||||||
|
An attempt was made to operate on a modal dialog when one was not open.
|
||||||
|
"
|
||||||
|
Class {
|
||||||
|
#name : #WDNoSuchAlert,
|
||||||
|
#superclass : #WDException,
|
||||||
|
#category : #'WebDriver-Exception'
|
||||||
|
}
|
||||||
|
|
||||||
|
{ #category : #testing }
|
||||||
|
WDNoSuchAlert class >> matchesErrorCode: errCode [
|
||||||
|
^ errCode = 'no such alert'
|
||||||
|
]
|
|
@ -0,0 +1,13 @@
|
||||||
|
"
|
||||||
|
No cookie matching the given path name was found amongst the associated cookies of the current browsing context’s active document.
|
||||||
|
"
|
||||||
|
Class {
|
||||||
|
#name : #WDNoSuchCookie,
|
||||||
|
#superclass : #WDException,
|
||||||
|
#category : #'WebDriver-Exception'
|
||||||
|
}
|
||||||
|
|
||||||
|
{ #category : #testing }
|
||||||
|
WDNoSuchCookie class >> matchesErrorCode: errCode [
|
||||||
|
^ errCode = 'no such cookie'
|
||||||
|
]
|
|
@ -0,0 +1,13 @@
|
||||||
|
"
|
||||||
|
An element could not be located on the page using the given search parameters.
|
||||||
|
"
|
||||||
|
Class {
|
||||||
|
#name : #WDNoSuchElement,
|
||||||
|
#superclass : #WDException,
|
||||||
|
#category : #'WebDriver-Exception'
|
||||||
|
}
|
||||||
|
|
||||||
|
{ #category : #testing }
|
||||||
|
WDNoSuchElement class >> matchesErrorCode: errCode [
|
||||||
|
^ errCode = 'no such element'
|
||||||
|
]
|
|
@ -0,0 +1,13 @@
|
||||||
|
"
|
||||||
|
A command to switch to a frame could not be satisfied because the frame could not be found.
|
||||||
|
"
|
||||||
|
Class {
|
||||||
|
#name : #WDNoSuchFrame,
|
||||||
|
#superclass : #WDException,
|
||||||
|
#category : #'WebDriver-Exception'
|
||||||
|
}
|
||||||
|
|
||||||
|
{ #category : #testing }
|
||||||
|
WDNoSuchFrame class >> matchesErrorCode: errCode [
|
||||||
|
^ errCode = 'no such frame'
|
||||||
|
]
|
|
@ -0,0 +1,13 @@
|
||||||
|
"
|
||||||
|
The element does not have a shadow root.
|
||||||
|
"
|
||||||
|
Class {
|
||||||
|
#name : #WDNoSuchShadowRoot,
|
||||||
|
#superclass : #WDException,
|
||||||
|
#category : #'WebDriver-Exception'
|
||||||
|
}
|
||||||
|
|
||||||
|
{ #category : #testing }
|
||||||
|
WDNoSuchShadowRoot class >> matchesErrorCode: errCode [
|
||||||
|
^ errCode = 'no such shadow root'
|
||||||
|
]
|
|
@ -0,0 +1,13 @@
|
||||||
|
"
|
||||||
|
A command to switch to a window could not be satisfied because the window could not be found.
|
||||||
|
"
|
||||||
|
Class {
|
||||||
|
#name : #WDNoSuchWindow,
|
||||||
|
#superclass : #WDException,
|
||||||
|
#category : #'WebDriver-Exception'
|
||||||
|
}
|
||||||
|
|
||||||
|
{ #category : #testing }
|
||||||
|
WDNoSuchWindow class >> matchesErrorCode: errCode [
|
||||||
|
^ errCode = 'no such window'
|
||||||
|
]
|
|
@ -0,0 +1,13 @@
|
||||||
|
"
|
||||||
|
An operation did not complete before its timeout expired.
|
||||||
|
"
|
||||||
|
Class {
|
||||||
|
#name : #WDScriptTimeout,
|
||||||
|
#superclass : #WDException,
|
||||||
|
#category : #'WebDriver-Exception'
|
||||||
|
}
|
||||||
|
|
||||||
|
{ #category : #testing }
|
||||||
|
WDScriptTimeout class >> matchesErrorCode: errCode [
|
||||||
|
^ errCode = 'script timeout'
|
||||||
|
]
|
|
@ -0,0 +1,13 @@
|
||||||
|
"
|
||||||
|
A new session could not be created.
|
||||||
|
"
|
||||||
|
Class {
|
||||||
|
#name : #WDSessionNotCreated,
|
||||||
|
#superclass : #WDException,
|
||||||
|
#category : #'WebDriver-Exception'
|
||||||
|
}
|
||||||
|
|
||||||
|
{ #category : #testing }
|
||||||
|
WDSessionNotCreated class >> matchesErrorCode: errCode [
|
||||||
|
^ errCode = 'session not created'
|
||||||
|
]
|
|
@ -0,0 +1,13 @@
|
||||||
|
"
|
||||||
|
A command failed because the referenced element is no longer attached to the DOM.
|
||||||
|
"
|
||||||
|
Class {
|
||||||
|
#name : #WDStaleElementReference,
|
||||||
|
#superclass : #WDException,
|
||||||
|
#category : #'WebDriver-Exception'
|
||||||
|
}
|
||||||
|
|
||||||
|
{ #category : #testing }
|
||||||
|
WDStaleElementReference class >> matchesErrorCode: errCode [
|
||||||
|
^ errCode = 'stale element reference'
|
||||||
|
]
|
|
@ -0,0 +1,13 @@
|
||||||
|
"
|
||||||
|
An operation did not complete before its timeout expired.
|
||||||
|
"
|
||||||
|
Class {
|
||||||
|
#name : #WDTimeout,
|
||||||
|
#superclass : #WDException,
|
||||||
|
#category : #'WebDriver-Exception'
|
||||||
|
}
|
||||||
|
|
||||||
|
{ #category : #testing }
|
||||||
|
WDTimeout class >> matchesErrorCode: errCode [
|
||||||
|
^ errCode = 'timeout'
|
||||||
|
]
|
|
@ -0,0 +1,13 @@
|
||||||
|
"
|
||||||
|
A screen capture was made impossible.
|
||||||
|
"
|
||||||
|
Class {
|
||||||
|
#name : #WDUnableToCaptureScreen,
|
||||||
|
#superclass : #WDException,
|
||||||
|
#category : #'WebDriver-Exception'
|
||||||
|
}
|
||||||
|
|
||||||
|
{ #category : #testing }
|
||||||
|
WDUnableToCaptureScreen class >> matchesErrorCode: errCode [
|
||||||
|
^ errCode = 'unable to capture screen'
|
||||||
|
]
|
|
@ -0,0 +1,13 @@
|
||||||
|
"
|
||||||
|
A command to set a cookie’s value could not be satisfied.
|
||||||
|
"
|
||||||
|
Class {
|
||||||
|
#name : #WDUnableToSetCookie,
|
||||||
|
#superclass : #WDException,
|
||||||
|
#category : #'WebDriver-Exception'
|
||||||
|
}
|
||||||
|
|
||||||
|
{ #category : #testing }
|
||||||
|
WDUnableToSetCookie class >> matchesErrorCode: errCode [
|
||||||
|
^ errCode = 'unable to set cookie'
|
||||||
|
]
|
|
@ -0,0 +1,13 @@
|
||||||
|
"
|
||||||
|
A modal dialog was open, blocking this operation.
|
||||||
|
"
|
||||||
|
Class {
|
||||||
|
#name : #WDUnexpectedAlertOpen,
|
||||||
|
#superclass : #WDException,
|
||||||
|
#category : #'WebDriver-Exception'
|
||||||
|
}
|
||||||
|
|
||||||
|
{ #category : #testing }
|
||||||
|
WDUnexpectedAlertOpen class >> matchesErrorCode: errCode [
|
||||||
|
^ errCode = 'unexpected alert open'
|
||||||
|
]
|
|
@ -0,0 +1,13 @@
|
||||||
|
"
|
||||||
|
A command could not be executed because the remote end is not aware of it.
|
||||||
|
"
|
||||||
|
Class {
|
||||||
|
#name : #WDUnknownCommand,
|
||||||
|
#superclass : #WDException,
|
||||||
|
#category : #'WebDriver-Exception'
|
||||||
|
}
|
||||||
|
|
||||||
|
{ #category : #testing }
|
||||||
|
WDUnknownCommand class >> matchesErrorCode: errCode [
|
||||||
|
^ errCode = 'unknown command'
|
||||||
|
]
|
|
@ -0,0 +1,13 @@
|
||||||
|
"
|
||||||
|
An unknown error occurred in the remote end while processing the command.
|
||||||
|
"
|
||||||
|
Class {
|
||||||
|
#name : #WDUnknownError,
|
||||||
|
#superclass : #WDException,
|
||||||
|
#category : #'WebDriver-Exception'
|
||||||
|
}
|
||||||
|
|
||||||
|
{ #category : #testing }
|
||||||
|
WDUnknownError class >> matchesErrorCode: errCode [
|
||||||
|
^ errCode = 'unknown error'
|
||||||
|
]
|
|
@ -0,0 +1,13 @@
|
||||||
|
"
|
||||||
|
The requested command matched a known URL but did not match any method for that URL.
|
||||||
|
"
|
||||||
|
Class {
|
||||||
|
#name : #WDUnknownMethod,
|
||||||
|
#superclass : #WDException,
|
||||||
|
#category : #'WebDriver-Exception'
|
||||||
|
}
|
||||||
|
|
||||||
|
{ #category : #testing }
|
||||||
|
WDUnknownMethod class >> matchesErrorCode: errCode [
|
||||||
|
^ errCode = 'unknown method'
|
||||||
|
]
|
|
@ -0,0 +1,13 @@
|
||||||
|
"
|
||||||
|
Indicates that a command that should have executed properly cannot be supported for some reason.
|
||||||
|
"
|
||||||
|
Class {
|
||||||
|
#name : #WDUnsupportedOperation,
|
||||||
|
#superclass : #WDException,
|
||||||
|
#category : #'WebDriver-Exception'
|
||||||
|
}
|
||||||
|
|
||||||
|
{ #category : #testing }
|
||||||
|
WDUnsupportedOperation class >> matchesErrorCode: errCode [
|
||||||
|
^ errCode = 'unsupported operation'
|
||||||
|
]
|
|
@ -1,5 +1,5 @@
|
||||||
"
|
"
|
||||||
I am a cleanroom implementation of the W3C WebDriver protocol.
|
I am a cleanroom implementation of the [W3C WebDriver protocol](https://w3c.github.io/webdriver/).
|
||||||
|
|
||||||
Please comment me using the following template inspired by Class Responsibility Collaborator (CRC) design:
|
Please comment me using the following template inspired by Class Responsibility Collaborator (CRC) design:
|
||||||
|
|
||||||
|
@ -36,8 +36,7 @@ Class {
|
||||||
'browser',
|
'browser',
|
||||||
'server',
|
'server',
|
||||||
'port',
|
'port',
|
||||||
'sessionId',
|
'sessionId'
|
||||||
'optionsName'
|
|
||||||
],
|
],
|
||||||
#category : #WebDriver
|
#category : #WebDriver
|
||||||
}
|
}
|
||||||
|
@ -51,8 +50,7 @@ WebDriver class >> geckodriver [
|
||||||
^ WebDriverGeckodriver new
|
^ WebDriverGeckodriver new
|
||||||
browser: subproc
|
browser: subproc
|
||||||
server: '127.0.0.1'
|
server: '127.0.0.1'
|
||||||
port: 4444
|
port: 4444.
|
||||||
optionsName: #moz:firefoxOptions.
|
|
||||||
]
|
]
|
||||||
|
|
||||||
{ #category : #accessing }
|
{ #category : #accessing }
|
||||||
|
@ -73,12 +71,11 @@ WebDriver >> back [
|
||||||
]
|
]
|
||||||
|
|
||||||
{ #category : #initialization }
|
{ #category : #initialization }
|
||||||
WebDriver >> browser: brs server: srv port: portnum optionsName: optName [
|
WebDriver >> browser: brs server: srv port: portnum [
|
||||||
|
|
||||||
browser := brs.
|
browser := brs.
|
||||||
server := srv.
|
server := srv.
|
||||||
port := portnum.
|
port := portnum.
|
||||||
optionsName := optName
|
|
||||||
]
|
]
|
||||||
|
|
||||||
{ #category : #'event handling' }
|
{ #category : #'event handling' }
|
||||||
|
@ -177,7 +174,7 @@ WebDriver >> session [
|
||||||
|
|
||||||
sessionId ifNil: [
|
sessionId ifNil: [
|
||||||
sessionId := (self
|
sessionId := (self
|
||||||
send: (self constructCapabilities: { })
|
send: (self constructCapabilities: { } asDictionary)
|
||||||
to: 'session'
|
to: 'session'
|
||||||
using: #POST) at: #sessionId ].
|
using: #POST) at: #sessionId ].
|
||||||
^ sessionId
|
^ sessionId
|
||||||
|
|
|
@ -10,10 +10,10 @@ Class {
|
||||||
{ #category : #'private - utilities' }
|
{ #category : #'private - utilities' }
|
||||||
WebDriverGeckodriver >> constructCapabilities: caps [
|
WebDriverGeckodriver >> constructCapabilities: caps [
|
||||||
|
|
||||||
^ { (#desiredCapabilities
|
^ { #desiredCapabilities
|
||||||
->
|
->
|
||||||
{ (optionsName -> { (#prefs -> caps) } asDictionary) }
|
({ #moz:firefoxOptions -> ({ #prefs -> caps } asDictionary) }
|
||||||
asDictionary) }
|
asDictionary) } asDictionary.
|
||||||
]
|
]
|
||||||
|
|
||||||
{ #category : #navigation }
|
{ #category : #navigation }
|
||||||
|
|
Loading…
Reference in New Issue