265 lines
5.9 KiB
Smalltalk
265 lines
5.9 KiB
Smalltalk
"
|
|
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:
|
|
|
|
For the Class part: State a one line summary. For example, ""I represent a paragraph of text"".
|
|
|
|
For the Responsibility part: Three sentences about my main responsibilities - what I do, what I know.
|
|
|
|
For the Collaborators Part: State my main collaborators and one line about how I interact with them.
|
|
|
|
Public API and Key Messages
|
|
|
|
- message one
|
|
- message two
|
|
- (for bonus points) how to create instances.
|
|
|
|
One simple example is simply gorgeous.
|
|
|
|
Internal Representation and Key Implementation Points.
|
|
|
|
Instance Variables
|
|
browser: <Object>
|
|
optionsName: <Object>
|
|
port: <Object>
|
|
server: <Object>
|
|
sessionId: <Object>
|
|
|
|
|
|
Implementation Points
|
|
"
|
|
Class {
|
|
#name : #WebDriver,
|
|
#superclass : #Object,
|
|
#instVars : [
|
|
'browser',
|
|
'server',
|
|
'port',
|
|
'sessionId',
|
|
'prefs'
|
|
],
|
|
#category : #'WebDriver-Base'
|
|
}
|
|
|
|
{ #category : #testing }
|
|
WebDriver class >> matchesBrowserType: browserType [
|
|
^ self subclassResponsibility.
|
|
]
|
|
|
|
{ #category : #accessing }
|
|
WebDriver class >> start: browserType [
|
|
| emptyOpts |
|
|
emptyOpts := Dictionary new.
|
|
^ self start: browserType with: emptyOpts.
|
|
]
|
|
|
|
{ #category : #'instance creation' }
|
|
WebDriver class >> start: browserType with: options [
|
|
"comment stating purpose of class-side method"
|
|
"scope: class-variables & class-instance-variables"
|
|
|
|
| matchingClass |
|
|
matchingClass := self subclasses
|
|
detect: [ :operationClass | operationClass matchesBrowserType: browserType ]
|
|
ifNone: [ self ].
|
|
^ matchingClass startWithOptions: options.
|
|
]
|
|
|
|
{ #category : #'instance creation' }
|
|
WebDriver class >> startWithOptions: options [
|
|
^ self subclassResponsibility.
|
|
]
|
|
|
|
{ #category : #accessing }
|
|
WebDriver >> atPref: prefKey put: prefVal [
|
|
prefs at: prefKey put: prefVal.
|
|
]
|
|
|
|
{ #category : #navigation }
|
|
WebDriver >> back [
|
|
|
|
self send: { } to: 'session/' , sessionId , '/back' using: #POST
|
|
]
|
|
|
|
{ #category : #initialization }
|
|
WebDriver >> browser: brs server: srv port: portnum [
|
|
|
|
browser := brs.
|
|
server := srv.
|
|
port := portnum.
|
|
]
|
|
|
|
{ #category : #'private - utilities' }
|
|
WebDriver >> constructCapabilities: caps [
|
|
|
|
self subclassResponsibility
|
|
]
|
|
|
|
{ #category : #finalization }
|
|
WebDriver >> deleteSession [
|
|
|
|
"Deletes the session."
|
|
|
|
self send: { } to: 'session/' , sessionId using: #DELETE
|
|
]
|
|
|
|
{ #category : #finalization }
|
|
WebDriver >> finalize [
|
|
|
|
browser terminate.
|
|
super finalize
|
|
]
|
|
|
|
{ #category : #accessing }
|
|
WebDriver >> findElement: elemSelector using: locStrategy [
|
|
|
|
| reply |
|
|
reply := self
|
|
send: {
|
|
(#using -> locStrategy).
|
|
(#value -> elemSelector) }
|
|
to: 'session/' , sessionId , '/element'
|
|
using: #POST.
|
|
^ WDElement new
|
|
driver: self;
|
|
element: reply values first.
|
|
]
|
|
|
|
{ #category : #accessing }
|
|
WebDriver >> findElements: elemSelector using: locStrategy [
|
|
|
|
| reply |
|
|
reply := self
|
|
send: {
|
|
(#using -> locStrategy).
|
|
(#value -> elemSelector) }
|
|
to: 'session/' , sessionId , '/elements'
|
|
using: #POST.
|
|
^ reply collect: [ :elem | WDElement new driver: self; element: elem values first. ]
|
|
]
|
|
|
|
{ #category : #navigation }
|
|
WebDriver >> forward [
|
|
|
|
self send: { } to: 'session/' , sessionId , '/forward' using: #POST
|
|
]
|
|
|
|
{ #category : #'private - utilities' }
|
|
WebDriver >> postprocessResult: result [
|
|
^ result.
|
|
]
|
|
|
|
{ #category : #navigation }
|
|
WebDriver >> refresh [
|
|
|
|
self send: { } to: 'session/' , sessionId , '/refresh' using: #POST
|
|
]
|
|
|
|
{ #category : #'private - utilities' }
|
|
WebDriver >> send: dict to: url using: method [
|
|
|result|
|
|
result := nil.
|
|
ZnClient new
|
|
host: server;
|
|
port: port;
|
|
path: url;
|
|
contents: (NeoJSONWriter toString: dict asDictionary);
|
|
contentType: ZnMimeType applicationJson;
|
|
method: method;
|
|
contentReader: [ :entity |
|
|
result := (NeoJSONReader on: (entity contents) readStream) propertyNamesAsSymbols: true; next.
|
|
result := self postprocessResult: result.
|
|
(result keys contains: #error) ifTrue: [ WDException raise: result ].
|
|
];
|
|
execute.
|
|
^result.
|
|
]
|
|
|
|
{ #category : #'private - utilities' }
|
|
WebDriver >> sendWithSession: dict to: url using: method [
|
|
^ self send: dict to: '/session/' , sessionId , '/' , url using: method
|
|
]
|
|
|
|
{ #category : #accessing }
|
|
WebDriver >> session [
|
|
|
|
"Initializes a new WebDriver session."
|
|
|
|
sessionId ifNil: [
|
|
sessionId := (self
|
|
send: (self constructCapabilities: { } asDictionary)
|
|
to: 'session'
|
|
using: #POST) at: #sessionId ].
|
|
^ sessionId
|
|
]
|
|
|
|
{ #category : #accessing }
|
|
WebDriver >> session: capabilities [
|
|
|
|
sessionId ifNotNil: [ ^ self session ] ifNil: [
|
|
sessionId := (self
|
|
send: (self constructCapabilities: capabilities)
|
|
to: 'session'
|
|
using: #POST) at: #sessionId.
|
|
^ sessionId ]
|
|
]
|
|
|
|
{ #category : #accessing }
|
|
WebDriver >> source [
|
|
|
|
^ (self
|
|
send: { }
|
|
to:
|
|
'session/' , sessionId , '/source'
|
|
using: #GET)
|
|
]
|
|
|
|
{ #category : #accessing }
|
|
WebDriver >> status [
|
|
|
|
^ self send: { } to: 'status' using: #GET
|
|
]
|
|
|
|
{ #category : #accessing }
|
|
WebDriver >> timeouts [
|
|
| toutdata |
|
|
toutdata := self send: { } to: 'session/',sessionId,'/timeouts' using: #GET.
|
|
^ WDTimeouts new
|
|
script: (toutdata at: #script);
|
|
pageLoad: (toutdata at: #pageLoad);
|
|
implicit: (toutdata at: #implicit).
|
|
]
|
|
|
|
{ #category : #accessing }
|
|
WebDriver >> timeouts: timeouts [
|
|
|
|
self
|
|
send: timeouts extract
|
|
to: 'session/' , sessionId , 'timeouts'
|
|
using: #POST
|
|
]
|
|
|
|
{ #category : #accessing }
|
|
WebDriver >> title [
|
|
|
|
^ self send: { } to: 'session/' , sessionId , '/title' using: #GET
|
|
]
|
|
|
|
{ #category : #accessing }
|
|
WebDriver >> url [
|
|
|
|
^ self send: { } to: 'session/' , sessionId , '/url' using: #GET
|
|
]
|
|
|
|
{ #category : #navigation }
|
|
WebDriver >> url: url [
|
|
|
|
"Navigates the browser to the given URL."
|
|
|
|
self
|
|
send: { (#url -> url) }
|
|
to: 'session/' , sessionId , '/url'
|
|
using: #POST
|
|
]
|