1
+ const { Builder, By, until } = require ( "selenium-webdriver" ) ;
2
+ const { Select } = require ( 'selenium-webdriver/lib/select' ) ;
3
+ const chrome = require ( "selenium-webdriver/chrome" ) ;
4
+ const jwt = require ( "jsonwebtoken" ) ;
5
+ const assert = require ( "assert" ) ;
6
+
7
+ async function populateMetadata ( driver , discovery_endpoint ) {
8
+ oidc_discovery_endpoint = By . id ( "oidc_discovery_endpoint" ) ;
9
+ btn_oidc_discovery_endpoint = By . className ( "btn_oidc_discovery_endpoint" ) ;
10
+ btn_oidc_populate_meta_data = By . className ( "btn_oidc_populate_meta_data" ) ;
11
+
12
+ // Wait until page is loaded
13
+ await driver . wait ( until . elementLocated ( oidc_discovery_endpoint ) , 10000 ) ;
14
+ await driver . wait ( until . elementIsVisible ( driver . findElement ( oidc_discovery_endpoint ) ) , 10000 ) ;
15
+
16
+ // Enter discovery endpoint
17
+ await driver . findElement ( oidc_discovery_endpoint ) . clear ( ) ;
18
+ await driver . findElement ( oidc_discovery_endpoint ) . sendKeys ( discovery_endpoint ) ;
19
+ await driver . findElement ( btn_oidc_discovery_endpoint ) . click ( ) ;
20
+
21
+ // Populate metadata
22
+ await driver . wait ( until . elementLocated ( btn_oidc_populate_meta_data ) , 10000 ) ;
23
+ await driver . wait ( until . elementIsVisible ( driver . findElement ( btn_oidc_populate_meta_data ) ) , 10000 ) ;
24
+ await driver . executeScript ( "arguments[0].scrollIntoView({ behavior: 'smooth', block: 'center' });" , await driver . findElement ( btn_oidc_populate_meta_data ) ) ;
25
+ await driver . findElement ( btn_oidc_populate_meta_data ) . click ( ) ;
26
+ }
27
+
28
+ async function getAccessToken ( driver , client_id , client_secret , scope ) {
29
+ authorization_grant_type = By . id ( "authorization_grant_type" ) ;
30
+ token_client_id = By . id ( "token_client_id" ) ;
31
+ token_client_secret = By . id ( "token_client_secret" ) ;
32
+ token_scope = By . id ( "token_scope" ) ;
33
+ btn1 = By . className ( "btn1" ) ;
34
+ token_access_token = By . id ( "token_access_token" ) ;
35
+ display_token_error_form_textarea1 = By . id ( "display_token_error_form_textarea1" ) ;
36
+
37
+ // Select client credential login type
38
+ await new Select ( await driver . findElement ( authorization_grant_type ) ) . selectByVisibleText ( 'OAuth2 Client Credential' ) ;
39
+ await driver . wait ( until . elementLocated ( token_client_id ) , 10000 ) ;
40
+ await driver . wait ( until . elementIsVisible ( driver . findElement ( token_client_id ) ) , 10000 ) ;
41
+
42
+ // Submit credentials
43
+ await driver . findElement ( token_client_id ) . clear ( ) ;
44
+ await driver . findElement ( token_client_id ) . sendKeys ( client_id ) ;
45
+ await driver . findElement ( token_client_secret ) . clear ( ) ;
46
+ await driver . findElement ( token_client_secret ) . sendKeys ( client_secret ) ;
47
+ await driver . findElement ( token_scope ) . clear ( ) ;
48
+ await driver . findElement ( token_scope ) . sendKeys ( scope ) ;
49
+ await driver . findElement ( btn1 ) . click ( ) ;
50
+
51
+ // Get access token result
52
+ async function waitForVisibility ( element ) {
53
+ await driver . wait ( until . elementLocated ( element ) , 10000 ) ;
54
+ await driver . wait ( until . elementIsVisible ( driver . findElement ( element ) ) , 10000 ) ;
55
+ return element ;
56
+ }
57
+
58
+ let visibleAccessTokenElement = await Promise . any ( [
59
+ waitForVisibility ( token_access_token ) ,
60
+ waitForVisibility ( display_token_error_form_textarea1 )
61
+ ] ) ;
62
+
63
+ return await driver . findElement ( visibleAccessTokenElement ) . getAttribute ( "value" ) ;
64
+ }
65
+
66
+ async function verifyAccessToken ( access_token , client_id , scope ) {
67
+ async function compareScopes ( scope1 , scope2 ) {
68
+ scope1 = scope1 . split ( " " ) ;
69
+ scope2 = scope2 . split ( " " ) ;
70
+
71
+ return scope2 . every ( element => scope1 . includes ( element ) ) ;
72
+ }
73
+
74
+ let decoded_access_token = jwt . decode ( access_token , { complete : true } ) ;
75
+ let response_text = access_token . match ( / r e s p o n s e T e x t : ( .* ) / ) ;
76
+
77
+ assert . notStrictEqual ( decoded_access_token , null , "Cannot decode access token. Request result: " + ( response_text ? response_text [ 1 ] : "no response text" ) ) ;
78
+ assert . strictEqual ( decoded_access_token . payload . client_id , client_id , "Access token client ID does not match client ID." ) ;
79
+ assert . strictEqual ( await compareScopes ( decoded_access_token . payload . scope , scope ) , true , "Access token scope does not match scope." ) ;
80
+ }
81
+
82
+ async function test ( ) {
83
+ const options = new chrome . Options ( ) ;
84
+ options . addArguments ( "--headless" ) ;
85
+ options . addArguments ( "--no-sandbox" ) ;
86
+ const driver = await new Builder ( ) . forBrowser ( "chrome" ) . setChromeOptions ( options ) . build ( ) ;
87
+
88
+ try {
89
+ const discovery_endpoint = process . env . DISCOVERY_ENDPOINT ;
90
+ const client_id = process . env . CLIENT_ID ;
91
+ const client_secret = process . env . CLIENT_SECRET ;
92
+ const scope = process . env . SCOPE ;
93
+
94
+ assert ( discovery_endpoint , "DISCOVERY_ENDPOINT environment variable is not set." ) ;
95
+ assert ( client_id , "CLIENT_ID environment variable is not set." ) ;
96
+ assert ( client_secret , "CLIENT_SECRET environment variable is not set." ) ;
97
+ assert ( scope , "SCOPE environment variable is not set." ) ;
98
+
99
+ await driver . get ( "http://localhost:3000" ) ;
100
+ await populateMetadata ( driver , discovery_endpoint ) ;
101
+ let access_token = await getAccessToken ( driver , client_id , client_secret , scope ) ;
102
+ await verifyAccessToken ( access_token , client_id , scope ) ;
103
+ console . log ( "Test completed successfully." )
104
+ } catch ( error ) {
105
+ console . log ( error . message ) ;
106
+ process . exit ( 1 ) ;
107
+ } finally {
108
+ await driver . quit ( ) ;
109
+ }
110
+ }
111
+
112
+ test ( ) ;
0 commit comments