From 5456f2603edca1f4bb369aa4502f79ffca73a377 Mon Sep 17 00:00:00 2001 From: Sergio Eduardo Castro Ceballos <72516762+SergioCasCeb@users.noreply.github.com> Date: Fri, 13 Oct 2023 15:03:12 +0200 Subject: [PATCH] Add playwright testing for the new web package --- packages/web-new/package-lock.json | 60 ++ packages/web-new/package.json | 1 + packages/web-new/playwright.config.js | 72 ++ .../trace.zip | Bin 0 -> 962 bytes .../trace.zip | Bin 0 -> 961 bytes .../trace.zip | Bin 0 -> 961 bytes .../trace.zip | Bin 0 -> 965 bytes .../trace.zip | Bin 0 -> 959 bytes .../trace.zip | Bin 0 -> 960 bytes packages/web-new/tests/test.spec.js | 946 ++++++++++++++++++ 10 files changed, 1079 insertions(+) create mode 100644 packages/web-new/playwright.config.js create mode 100644 packages/web-new/test-results/test-Load-initial-state-Has-TD-template-chromium/trace.zip create mode 100644 packages/web-new/test-results/test-Load-initial-state-Has-editor-tab-chromium/trace.zip create mode 100644 packages/web-new/test-results/test-Load-initial-state-Has-title-chromium/trace.zip create mode 100644 packages/web-new/test-results/test-Load-initial-state-JSON-button-is-checked-chromium/trace.zip create mode 100644 packages/web-new/test-results/test-Load-initial-state-Validation-tab-is-checked-chromium/trace.zip create mode 100644 packages/web-new/test-results/test-Load-initial-state-Validation-view-is-opened-chromium/trace.zip create mode 100644 packages/web-new/tests/test.spec.js diff --git a/packages/web-new/package-lock.json b/packages/web-new/package-lock.json index d17b93b82..c47e76fbf 100644 --- a/packages/web-new/package-lock.json +++ b/packages/web-new/package-lock.json @@ -23,6 +23,7 @@ "devDependencies": { "@babel/core": "^7.22.9", "@babel/preset-env": "^7.22.9", + "@playwright/test": "^1.39.0", "babel-loader": "^9.1.3", "copy-webpack-plugin": "^11.0.0", "css-loader": "^6.8.1", @@ -1913,6 +1914,21 @@ "node": ">= 8" } }, + "node_modules/@playwright/test": { + "version": "1.39.0", + "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.39.0.tgz", + "integrity": "sha512-3u1iFqgzl7zr004bGPYiN/5EZpRUSFddQBra8Rqll5N0/vfpqlP9I9EXqAoGacuAbX6c9Ulg/Cjqglp5VkK6UQ==", + "dev": true, + "dependencies": { + "playwright": "1.39.0" + }, + "bin": { + "playwright": "cli.js" + }, + "engines": { + "node": ">=16" + } + }, "node_modules/@polka/url": { "version": "1.0.0-next.23", "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.23.tgz", @@ -5952,6 +5968,50 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/playwright": { + "version": "1.39.0", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.39.0.tgz", + "integrity": "sha512-naE5QT11uC/Oiq0BwZ50gDmy8c8WLPRTEWuSSFVG2egBka/1qMoSqYQcROMT9zLwJ86oPofcTH2jBY/5wWOgIw==", + "dev": true, + "dependencies": { + "playwright-core": "1.39.0" + }, + "bin": { + "playwright": "cli.js" + }, + "engines": { + "node": ">=16" + }, + "optionalDependencies": { + "fsevents": "2.3.2" + } + }, + "node_modules/playwright-core": { + "version": "1.39.0", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.39.0.tgz", + "integrity": "sha512-+k4pdZgs1qiM+OUkSjx96YiKsXsmb59evFoqv8SKO067qBA+Z2s/dCzJij/ZhdQcs2zlTAgRKfeiiLm8PQ2qvw==", + "dev": true, + "bin": { + "playwright-core": "cli.js" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/playwright/node_modules/fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, "node_modules/postcss": { "version": "8.4.31", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz", diff --git a/packages/web-new/package.json b/packages/web-new/package.json index 3a0af097b..e6d4ebcd1 100644 --- a/packages/web-new/package.json +++ b/packages/web-new/package.json @@ -23,6 +23,7 @@ "devDependencies": { "@babel/core": "^7.22.9", "@babel/preset-env": "^7.22.9", + "@playwright/test": "^1.39.0", "babel-loader": "^9.1.3", "copy-webpack-plugin": "^11.0.0", "css-loader": "^6.8.1", diff --git a/packages/web-new/playwright.config.js b/packages/web-new/playwright.config.js new file mode 100644 index 000000000..a334a4854 --- /dev/null +++ b/packages/web-new/playwright.config.js @@ -0,0 +1,72 @@ +// @ts-check +const { defineConfig, devices } = require('@playwright/test'); + +/** + * Read environment variables from file. + * https://github.com/motdotla/dotenv + */ +// require('dotenv').config(); + +/** + * @see https://playwright.dev/docs/test-configuration + */ +module.exports = defineConfig({ + testDir: './tests', + // Folder for test artifacts such as screenshots, videos, traces, etc. + outputDir: 'test-results', + /* Run tests in files in parallel */ + fullyParallel: true, + /* Fail the build on CI if you accidentally left test.only in the source code. */ + forbidOnly: !!process.env.CI, + /* Retry on CI only */ + retries: process.env.CI ? 2 : 0, + /* Opt out of parallel tests on CI. */ + workers: process.env.CI ? 1 : undefined, + /* Reporter to use. See https://playwright.dev/docs/test-reporters */ + reporter: 'html', + /* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */ + use: { + /* Base URL to use in actions like `await page.goto('/')`. */ + baseURL: 'http://127.0.0.1:5100', + + /* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */ + trace: 'on-first-retry', + }, + + /* Configure projects for major browsers */ + projects: [ + { + name: 'chromium', + use: { ...devices['Desktop Chrome'] }, + // use: { ...devices['Desktop Chrome'], headless: false, slowMo: 500}, + }, + + { + name: 'firefox', + use: { ...devices['Desktop Firefox'] }, + }, + + { + name: 'webkit', + use: { ...devices['Desktop Safari'] }, + }, + + /* Test against branded browsers. */ + { + name: 'Microsoft Edge', + use: { ...devices['Desktop Edge'], channel: 'msedge' }, + }, + { + name: 'Google Chrome', + use: { ...devices['Desktop Chrome'], channel: 'chrome' }, + }, + ], + + /* Run your local dev server before starting the tests */ + webServer: { + command: 'npm run serve', + url: 'http://127.0.0.1:5100', + reuseExistingServer: !process.env.CI, + }, +}); + diff --git a/packages/web-new/test-results/test-Load-initial-state-Has-TD-template-chromium/trace.zip b/packages/web-new/test-results/test-Load-initial-state-Has-TD-template-chromium/trace.zip new file mode 100644 index 0000000000000000000000000000000000000000..6d60317fcc127be4ad378b3c535014f126fa5639 GIT binary patch literal 962 zcmWIWW@Zs#VBp|jxLoENZYFS?--nrjp;3c@fs28Gp(M4qM6aYMF*)^ZRJ{Lf1A+Sc z%Qt-5Braw8clwrF%sC1UP8^wcFYjSD-)Y8pye}tR)2XK2S8A3?r~YyEn>$-C8J(KX z$Q0V=ms|Ah?%$f{f2vm1Jev8KY0o_KhJ_&y)>axmt}%D?)p~lds$mwF>0h1Wk&ery z&0aaG_uNV>K6|-M(^&SUiBz4oQ|y_U*D~(1=Uy;lpX~M8S6bu4OwpTmo7wIi_jK6Q z9B9HP;Uv?_Y1f+&#JagXywm3TK!N%A2KUIPaHZ>px(_y7B0vDK|X4 z6XsVO?z#PPe$|w^iwjJa{;>4YygQ|ErgFrUob^X}kvVl0n-Hyxa`YU9G0 zA>X$xYV^?azQFZ2P2l0Xsmj^?FU?+P&s9lS#jteArk|phwS2smm_B=OZPJ$$*CZZY z+Q7&@$>YMKy^03swkV#NP=9%Epvdeq243G)l$M%Y-};&*NNTy)v&fm(o2stts%eRu z+PS(~{+Pqjqc_)gZ1VXuzf)t!j?mY6O&qL?4%zgDF6|s#%F`HT*r0q}Qy{pW9 z{mjGSSZ+R7L$&L(A7%Oa7yMYmVQ(VdeejdI<)6>Ds^7Xky)%2`)a|J=Q@=Ssv3SyY zw6NpxgsBsXwf0=zZ8i6&TgkesoqzH!l&n1`E$$xNw=B#lX7%T+M;1p4Pk5c!yY}3h z`-gVgEq`6UxbJoGy&V>PMKW839{rjVE___E&pFIV?%Hz}?pnXy@7fbz{F-B~*SA>4 zeQnDQyXRMrKrEVFdv20)$y-(R6;9P5>Hk zmv8vANnFbG@BJ+P4UG((ic3oUKg->Da*IXAdehvc93N%PGBYlz?30r%fxqLM4F+mu zOGP)F-;;Rg?H7Mrul*STvx5G}9G#MP+Q45>C#y_&^K^cVvliB}nlrmO-d|*tX6zF) zSizy8VcOy8zrSX#;|uxQ86RC9F!8qNRnFsDf8A=ob;RM6oFdlQUsXS@TH6)AJ+do& z^~JBzj=u#z?uy&$&gLa1(e(dRaoCp&kJA?S)D$|OKCr!M0nff()?0jXliz4QvwQT( z^0cdj{-N(lYD#?bzn6dK|1HM<_|~Dm#)VazngVxTl{o5j;dW=$v91*w7c95C?VB6B zB1L32SDu;VrVB5;8ZN7ye)Q|4M}o`t#1j{iynA&_zVJG)S(stB?`UP^sT^m8ebafu zp7ipbRoQ>~5}VR4Kd0sIuCFRx6K}ccn?zpozDJ%6%eVr(w4~z=&mK~7jY{U3wrq)e z*)f4z<$so+g_tO@k5bNI8 z?khw(XWad5z^1iMuP!$BPelCB-0eRm%S7a<*;q0bneYp3)aRR+6&PyZ+gBW-&XnC; z-0`Nxrh7)?3H2A*uRe4zUv>!5>*#FcQGG7dY^}7=C%9&Q$HW;&oC;1VH668k%zIaP zY4*DhJJ(Hep4fZRH}K52FD&inyFNJYox?ND?&QPy*Vk@k>a?H!6CY0y z7dx)l=X}jcZ{>$`?_ZUOMPCeBeL2@OX7%S|M=wrUymG6+^;dglS@0FgY!WNVUv2z< zf5F1@nZM>nJ@_@pT(57jjQiTw9d^&J9x3d2JYnmE_OF(XJI`nS-rAR4d~b(ESCPn8 zu}8P&gbPD#$=hzJeeQy3xa`7B>5s+w14?(*U7g2S{XuY*?(Oiq#Yf)j2Y53w*)!wL gbijNE23s0I6e0@-c(byBL>Ph40!SAFGb#fE0D?fgQvd(} literal 0 HcmV?d00001 diff --git a/packages/web-new/test-results/test-Load-initial-state-Has-title-chromium/trace.zip b/packages/web-new/test-results/test-Load-initial-state-Has-title-chromium/trace.zip new file mode 100644 index 0000000000000000000000000000000000000000..64695147e8a234e6a4a13110a746ab0f4b82db00 GIT binary patch literal 961 zcmWIWW@Zs#VBp|jxLoENUb6PLzBe-iLz4yr0~Z4WLrH3JiC#%jVsh%+sCfU|1_Jf> zmv8vANnFbG@APfAm~#{yoH#P?Uf#oQzSE5HcwbJsrc+J3uhcA)PW|KRH+QyPGB`D# zktwv#FSqF1-M=-@|5UB2c{KB}%$|MbEfYf?tgRG$Tx0I$tMv3@Rl_VH(`J*yk&es7 z&0aaGzuC6?tf{~BvNJhLg5Upeyx>@TZj0M%#*F4|k~3VQ@^3lxo!9aIKGXDrogecg z*`7s(3h7;`85KoVU!`R$|E|C9cYp4k=Jkfgtch|BJFl-x;)|-&uV8s1*`_O|dW0>i z>DLkIrFZ=PUs?X8n{BD)(es5)FPHUn@oZd_W^HPHbi$=Mn;&nS)Y|b;PIiOggAC5Y zvl=D^HP86+=Ja(-mwyX=#r#>>G89WrcKbXC@_T>os>a+IP6w+#Pb)E;B}mQPzB(sXB(N|3jbcd9(QV*D%qakDBsW@4pQ>(C&DdKYHzPk?OX}h8;EM zxCB+ZKkRMkoN@U1-M4rDHXc2^W7`JdgcbAL3|4KBS{%VrWgL2bhjJEI$-%V~^V6qm z$*M1F>-KfmG1?V&JoEAf342-YGcVM7B%*RwY;0}Ym)KIRF|R+rAZ~8aRt16k+HBsh zj=7~p-M@W`O=+KwlktaYMX|Qi8@C=Wk^VB(N7x{^At>nPpRP#JWvZ8?iVLzmf2CwI z1t#8@z}%^t@$sI(j3u`O(oXDudGEw$-!zG()j|`4X1%;s%B0yVq`G;_i7dyxw|CXF zM9u74T`jNXaP;WS_1&B0S8MNoD^x$p*86PBa(4&5XP!#mjw%M}uJT%TGO_Vh$b)+i zWRk2Go=8qp_{RBbmZi;u1118Y97#e7$|rXodD7>pvYF?;dXkFRMv<6JGajVvf5dxN zeQNf*4?EX&IZyOI@pajbsLR4KcG`#d&t@4$d{b$!kE>q4cg39Q;%%R{>1;kz-zC$& zXM+V_q0Ad)G-(Rrs z{L7zT7d-zp$6T*(v5foLmK}D_uO2Dvcsyb1g!ZqNj!VyHw$=%>tUF)%_>sk_!Yf`K zuZ!b+W!f$HA~|>7e6C~Zd_AtHO)KY~h4aXAHzSihGww_W f%y(e0r4d9SvS5HWD;r3J5eO}SbTKfaGB5xDe3iY3 literal 0 HcmV?d00001 diff --git a/packages/web-new/test-results/test-Load-initial-state-JSON-button-is-checked-chromium/trace.zip b/packages/web-new/test-results/test-Load-initial-state-JSON-button-is-checked-chromium/trace.zip new file mode 100644 index 0000000000000000000000000000000000000000..374c1e6f9c34b1313d723b22eee026fea9288878 GIT binary patch literal 965 zcmWIWW@Zs#VBp|jxKidD{##3RvOhBeL$d}00~Z4WLrH3JiC#%jVsh%+sKD&o1_E{W z*9+9$^iGyBFMPD2y(~MEd$GthTi@z{H{NeTr}e0umt6Wkv3csj1@(FRQCY*JhgqJTle(oSeqHXZq!a zCjyHz_5>Ooq)5M9>b7lcRq!e1}Q=Uj>fc zXKPB6>|cDjcH(;J6-G&|$Yid6E6=6cI`mu5Rr_?5QaK)*to+Qo}dt+=LbY*B>5Z&&!Pd0XS z&77HHerEC;kGu#IZ}&Z%^ruG0U~#oUQpU#B$Hb(5wF$0USW;I%{qwU4vpE}o+%Sj; zG&eK4{7X+;y5q|(4#9N`1m;`l9ls`bIrl=inePD~Mla9Q&)R9BGp2cDpE-DG63>Z$ zER#-cP-LIvb>Y!YMT3)D70*n#e|c~8wCXbkUh&>8UYQG{w{tErIXOk=)2fWE&2`Uz z2}PCa<(;dY!60g{xBuUcKYMn5I_vk5yE1p@%nyHfPMoyyJYr|zvdT5|tjW)Sg;wG_ z%q-fk@U1vCMbe|TXOK8&!o)aELdWJibC!JVy;CZJ+r|TNl={l-AZsb=u z^Lsp=VO_Ig@xy>A!bQ6^@}8COxAS*>I9j$@V$F`}hu`<_z4mW)Ol9%5Pv3MmpQ-PX zY5$X6DD%i7Mfph=*ZW8QbI&DdSKWT~g~@(XeMijd&r6P8oU(XjufX+JHnS}F3S~A4 z7NxH?u8-ew;rW)oE97_EJ@4#(tZ_V0T5;X^N)xC_?|;oH+kBq$uiuk<&uvNzWu97O zDIfW2*{{~;EYqIT^5@p`H8)(Y$8K$3_4~Bi{&xO9KQH000OG0Mm9&SAI&emq`Nv0D&j~015yA0CZ(@bS`vqVPj?OT3=7w zFc5#=r?B#}7aBGFm$upiY#=~FXwulzyazYAHUY++YC%1tv78T$7hzO`^*}6?`HwY4o1;9 zkTbM@Bqveh%FW+#70^I`@|ck z+)n>6r1Y}}r76YFNkZwSjEW4wqGmfaJH?37oU`MJl7)!z9v!d=;Ajb>hJcb%gP3&n z~tPd>%qWod84iEP_#m)fmMh(3`1x!X432pbKt|d^@{T=_D}?Tx>dKkNU zJ*L~BuVj{hN&!kqW%DblD$GixHRj;fk_^e#6r#eg5eE`W(BiEjFio`~%#gp+y^-ge z%rHv#BqF6W(~au{QW_;nW@(W%f@Z&S`3Q|N6<7B@Oo57vv!54d-&a?D*(LrUdzPCC zPmh3noF|Fc7l%l-s4AHzhXtxrfqR2lwCKvW@!Nq~$c=Ms}U zA(6~7e4mJsSj19r$zp<={famAkkqcZ!>77x4n;mC*PG&MO^&0N%qa6Nz z>Am)>a_-I9%Gr^4cl1V zbHeWrP)h*+5-Ra z2&^b7$(p?R{h!ZwpI#4sx-s3a_(N5kJX=uX_Ghj=pZ7|bc1}^3X3X-sBC}NT9M_?| z-GTgv%C=u#v%d0{L28=vTDQ~uQjD{TmzhS%H=1S4ZuDI8bs6uIA7?&&X^3Qg|G30) zQ}^l&nG-XUB&GV)gZE$Ty#D)F?x(yO{(Z;Jh_qC4JS!6|-rPCkcK-nz=8b0;wcMCG z?SNc$^OV~!=T}XsySTt)=?_aEjk}WqCn`oLnDaIs3Cjec}BLTvqp;NEbF zA78^B3x3=cv(^2V*EETy|EG%MzFl~HtV;CfqqaQO`+Tb(+>Th__}uX1yhJ;v7`yb= zj!CXR;tsi-dHDI>xqAmE9zDEc+Xmr;74z05ge01}ZRGe8wrbu+r7W(JgKH<|r%%_C zRa@3J+m~I(XxFyB%gatb`t>p(!DV~GfeT5&yt*b|c$wEMtgzd6vaY9mbh;_*7`)kK_q@0JvBvR0 zZN+uxD@~#Hq|M*_L?AZ%q~xl+zsG>YaenE3ONMQk(yOb_{rJlo;LXTn&x||I0ka(# bY-t2hh#VN;&B_K6VFW@8AYBB^rwj}LgCMjf literal 0 HcmV?d00001 diff --git a/packages/web-new/tests/test.spec.js b/packages/web-new/tests/test.spec.js new file mode 100644 index 000000000..d59559c94 --- /dev/null +++ b/packages/web-new/tests/test.spec.js @@ -0,0 +1,946 @@ +const { test, expect } = require('@playwright/test') + +//Open the playground app before any test is runned +test.beforeEach(async ({ page }) => { + await page.goto('/') +}); + +test.describe("Load initial state", () => { + test('Has title', async ({ page }) => { + await expect(page).toHaveTitle("TD Playground") + }) + + test('Has editor tab', async ({ page }) => { + const editorTab = page.locator('#tab') + await expect(editorTab).toHaveText("TDThing TemplateCloseCancel") + }) + + test('Has TD template', async ({ page }) => { + const editor = page.locator('#editor1').getByRole('code').locator('div').filter({ hasText: '"title": "Thing Template",' }).nth(4) + await expect(editor).toHaveText('"title": "Thing Template",') + }) + + test('Validation tab is checked', async ({ page }) => { + const validationTab = page.locator('#validation-tab') + await expect(validationTab).toBeChecked() + }) + + test('Validation view is opened', async ({ page }) => { + const validationView = page.locator('#validation-view') + await expect(validationView).toHaveClass("console-view validation-view") + }) + + test('JSON button is checked', async ({ page }) => { + const jsonBtn = page.locator('#file-type-json') + await expect(jsonBtn).toBeChecked() + }) +}) + +test.describe("Check all links", () => { + test("Check Thingweb logo link", async ({ page }) => { + const thingwebPromise = page.waitForEvent('popup') + await page.locator(".logo").click() + const thingwebPage = await thingwebPromise + await expect(thingwebPage).toHaveTitle("Eclipse Thingweb") + await expect(thingwebPage).toHaveURL("https://www.thingweb.io") + }) + + test("Check CLI link", async ({ page }) => { + const cliPromise = page.waitForEvent('popup') + await page.locator(".cli-link").click() + const cliPage = await cliPromise + await expect(cliPage).toHaveURL("https://github.com/eclipse-thingweb/playground/tree/master/packages/cli") + }) + + test("Check Github link", async ({ page }) => { + const githubPromise = page.waitForEvent('popup') + await page.locator(".git-link").click() + const githubPage = await githubPromise + await expect(githubPage).toHaveTitle(/GitHub - eclipse-thingweb/) + await expect(githubPage).toHaveURL("https://github.com/eclipse-thingweb/playground") + }) + + test("Check Thingweb footer link", async ({ page }) => { + await page.locator('#settings-btn').click() + const thingwebPromise = page.waitForEvent('popup') + await page.locator("#thingweb-link").click() + const thingwebPage = await thingwebPromise + await expect(thingwebPage).toHaveTitle("Eclipse Thingweb") + await expect(thingwebPage).toHaveURL("https://www.thingweb.io") + }) + + test("Check Eclipse footer link", async ({ page }) => { + await page.locator('#settings-btn').click() + const eclipsePromise = page.waitForEvent('popup') + await page.locator("#eclipse-link").click() + const eclipsePage = await eclipsePromise + await expect(eclipsePage).toHaveTitle("The Community for Open Collaboration and Innovation | The Eclipse Foundation") + await expect(eclipsePage).toHaveURL("https://www.eclipse.org") + }) + + test("Check privacy policy footer link", async ({ page }) => { + await page.locator('#settings-btn').click() + const privacyPromise = page.waitForEvent('popup') + await page.locator("#privacy-link").click() + const privacyPage = await privacyPromise + await expect(privacyPage).toHaveTitle("Eclipse Foundation Website Privacy Policy | The Eclipse Foundation") + await expect(privacyPage).toHaveURL("https://www.eclipse.org/legal/privacy.php") + }) + + test("Check terms of use footer link", async ({ page }) => { + await page.locator('#settings-btn').click() + const termsPromise = page.waitForEvent('popup') + await page.locator("#terms-link").click() + const termsPage = await termsPromise + await expect(termsPage).toHaveTitle("Eclipse.org Terms of Use | The Eclipse Foundation") + await expect(termsPage).toHaveURL("https://www.eclipse.org/legal/termsofuse.php") + }) + + test("Check copyright agent footer link", async ({ page }) => { + await page.locator('#settings-btn').click() + const copyrightPromise = page.waitForEvent('popup') + await page.locator("#copyright-link").click() + const copyrightPage = await copyrightPromise + await expect(copyrightPage).toHaveTitle("Copyright Agent | The Eclipse Foundation") + await expect(copyrightPage).toHaveURL("https://www.eclipse.org/legal/copyright.php") + }) + + test("Check legal footer link", async ({ page }) => { + await page.locator('#settings-btn').click() + const legalPromise = page.waitForEvent('popup') + await page.locator("#legal-link").click() + const legalPage = await legalPromise + await expect(legalPage).toHaveTitle("Eclipse Foundation Legal Resources | The Eclipse Foundation") + await expect(legalPage).toHaveURL("https://www.eclipse.org/legal/") + }) +}) + +test.describe("Editors and Tabs creation and deletion", () => { + test("Adding a new editor and closing it", async ({ page }) => { + const editorTabs = page.locator("#tab") + const editors = page.locator(".editor") + await expect(editorTabs).toHaveCount(1) + await expect(editors).toHaveCount(1) + + const initialTab = page.locator("#tab").nth(0) + await expect(initialTab).toHaveAttribute('data-tab-id', "1") + await expect(initialTab).toHaveText("TDThing TemplateCloseCancel") + await expect(initialTab).toHaveClass("active") + + const initialEditor = page.locator("#editor1") + await expect(initialEditor).toHaveAttribute('data-ide-id', "1") + await expect(initialEditor).toHaveClass("editor active") + + await page.locator("#ide-tab-add").click() + await expect(editorTabs).toHaveCount(2) + await expect(editors).toHaveCount(2) + + await expect(initialTab).toHaveClass("") + await expect(initialEditor).toHaveClass("editor") + + const secondTab = page.locator("#tab").nth(1) + await expect(secondTab).toHaveAttribute('data-tab-id', "2") + await expect(secondTab).toHaveText("TDThing TemplateCloseCancel") + await expect(secondTab).toHaveClass("active") + + const secondEditor = page.locator("#editor2") + await expect(secondEditor).toHaveAttribute('data-ide-id', "2") + await expect(secondEditor).toHaveClass("editor active") + + await page.locator("#tab").nth(1).locator(".close-tab").click() + await page.locator('#tab').nth(1).locator(".confirm-btns > .confirm-tab-close").click() + + await expect(editorTabs).toHaveCount(1) + await expect(editors).toHaveCount(1) + + await expect(initialTab).toHaveClass("active") + await expect(initialEditor).toHaveClass("editor active") + }) + + test("Opening an example and closing initial editor", async ({ page }) => { + const editorTabs = page.locator("#tab") + const editors = page.locator(".editor") + await expect(editorTabs).toHaveCount(1) + await expect(editors).toHaveCount(1) + + const initialTab = page.locator("#tab").nth(0) + await expect(initialTab).toHaveAttribute('data-tab-id', "1") + await expect(initialTab).toHaveText("TDThing TemplateCloseCancel") + await expect(initialTab).toHaveClass("active") + + const initialEditor = page.locator("#editor1") + await expect(initialEditor).toHaveAttribute('data-ide-id', "1") + await expect(initialEditor).toHaveClass("editor active") + + await page.locator("#examples-btn").click() + await page.locator(".example").nth(0).click() + await page.locator(".example").nth(0).getByRole("button", { name: /Apply/ }).click() + + await expect(editorTabs).toHaveCount(2) + await expect(editors).toHaveCount(2) + + await expect(initialTab).toHaveClass("") + await expect(initialEditor).toHaveClass("editor") + + const exampleTab = page.locator("#tab").nth(1) + await expect(exampleTab).toHaveAttribute('data-tab-id', "2") + await expect(exampleTab).toHaveText("TDMyLampThingCloseCancel") + await expect(exampleTab).toHaveClass("active") + + const exampleEditor = page.locator("#editor2") + await expect(exampleEditor).toHaveAttribute('data-ide-id', "2") + await expect(exampleEditor).toHaveClass("editor active") + + await page.locator("#tab").nth(0).locator(".close-tab").click() + await page.locator('#tab').nth(0).locator(".confirm-btns > .confirm-tab-close").click() + + await expect(editorTabs).toHaveCount(1) + await expect(editors).toHaveCount(1) + }) +}) + +test.describe("JSON and YAML conversion", () => { + test("JSON to YAML and YAML to JSON", async ({ page }) => { + const editorTabs = page.locator("#tab") + const editors = page.locator(".editor") + await expect(editorTabs).toHaveCount(1) + await expect(editors).toHaveCount(1) + + const jsonYamlPopup = page.locator('.json-yaml-warning') + await expect(jsonYamlPopup).toHaveClass("json-yaml-warning closed") + + const initialEditor = page.locator("#editor1") + const jsonBtn = page.locator('#file-type-json') + const yamlBtn = page.locator('#file-type-yaml') + + await expect(initialEditor).toHaveAttribute('data-mode-id', "json") + await expect(jsonBtn).toBeChecked({ checked: true }) + await expect(yamlBtn).toBeChecked({ checked: false }) + + await yamlBtn.click() + await expect(jsonYamlPopup).toHaveClass("json-yaml-warning") + + await page.locator('#yaml-confirm-btn').click() + await expect(jsonYamlPopup).toHaveClass("json-yaml-warning closed") + await expect(initialEditor).toHaveAttribute('data-mode-id', "yaml") + await expect(jsonBtn).toBeChecked({ checked: false }) + await expect(yamlBtn).toBeChecked({ checked: true }) + + await jsonBtn.click() + await expect(initialEditor).toHaveAttribute('data-mode-id', "json") + await expect(jsonBtn).toBeChecked({ checked: true }) + await expect(yamlBtn).toBeChecked({ checked: false }) + }) + + test("Cancel YAML conversion", async ({ page }) => { + const editorTabs = page.locator("#tab") + const editors = page.locator(".editor") + await expect(editorTabs).toHaveCount(1) + await expect(editors).toHaveCount(1) + + const jsonYamlPopup = page.locator('.json-yaml-warning') + const initialEditor = page.locator("#editor1") + const jsonBtn = page.locator('#file-type-json') + const yamlBtn = page.locator('#file-type-yaml') + + await expect(jsonYamlPopup).toHaveClass("json-yaml-warning closed") + await expect(initialEditor).toHaveAttribute('data-mode-id', "json") + await expect(jsonBtn).toBeChecked({ checked: true }) + await expect(yamlBtn).toBeChecked({ checked: false }) + + await yamlBtn.click() + await expect(jsonYamlPopup).toHaveClass("json-yaml-warning") + + await page.locator('#yaml-cancel-btn').click() + await expect(jsonYamlPopup).toHaveClass("json-yaml-warning closed") + await expect(initialEditor).toHaveAttribute('data-mode-id', "json") + await expect(jsonBtn).toBeChecked({ checked: true }) + await expect(yamlBtn).toBeChecked({ checked: false }) + }) +}) + + +test.describe("Examples menu functionality", () => { + test("Open and close examples menu", async ({ page }) => { + + await expect(page.getByRole('heading', { name: 'Simple Default' })).toBeVisible({ visible: false }) + await page.locator("#examples-btn").click() + + await expect(page.getByRole('heading', { name: 'Simple Default' })).toBeVisible({ visible: true }) + await page.locator(".examples-menu-container__close > i").click() + + await expect(page.getByRole('heading', { name: 'Simple Default' })).toBeVisible({ visible: false }) + }) + + test("Open Basic TD from quick access", async ({ page }) => { + + await page.locator("#examples-btn").click() + + const basicExample = page.locator(".example").filter({ hasText: 'Basic TD' }).nth(0) + await expect(basicExample).toHaveClass("example") + + const quickAccessBtn = page.locator(".example").filter({ hasText: 'Basic TD' }).nth(0).getByRole("button").nth(0) + await quickAccessBtn.click() + + const exampleTab = page.locator("#tab").nth(1) + await expect(exampleTab).toHaveAttribute('data-tab-id', "2") + await expect(exampleTab).toHaveText("TDMyLampThingCloseCancel") + await expect(exampleTab).toHaveClass("active") + + const exampleEditor = page.locator("#editor2") + await expect(exampleEditor).toHaveAttribute('data-ide-id', "2") + await expect(exampleEditor).toHaveClass("editor active") + + }) + + test("Open Basic TD from apply button", async ({ page }) => { + + await page.locator("#examples-btn").click() + + const basicExample = page.locator(".example").filter({ hasText: 'Basic TD' }).nth(0) + await basicExample.click() + await expect(basicExample).toHaveClass("example open") + + const applyBtn = page.locator(".example").filter({ hasText: 'Basic TD' }).nth(0).getByRole("button").filter({ hasText: "Apply" }) + await applyBtn.click() + await expect(basicExample).toHaveClass("example") + + const exampleTab = page.locator("#tab").nth(1) + await expect(exampleTab).toHaveAttribute('data-tab-id', "2") + await expect(exampleTab).toHaveText("TDMyLampThingCloseCancel") + await expect(exampleTab).toHaveClass("active") + + const exampleEditor = page.locator("#editor2") + await expect(exampleEditor).toHaveAttribute('data-ide-id', "2") + await expect(exampleEditor).toHaveClass("editor active") + }) + + test("Open Basic TD and close with cancel button", async ({ page }) => { + await page.locator("#examples-btn").click() + + const basicTDExample = page.locator(".example").filter({ hasText: 'Basic TD' }).nth(0) + await basicTDExample.click() + await expect(basicTDExample).toHaveClass("example open") + + const cancelBtn = page.locator(".example").filter({ hasText: 'Basic TD' }).nth(0).getByRole("button").filter({ hasText: "Cancel" }) + await cancelBtn.click() + await expect(basicTDExample).toHaveClass("example") + }) + + test("Toggle between TD and TM examples", async ({ page }) => { + await page.locator("#examples-btn").click() + + const thingTypeToggle = page.locator('#thing-type-btn') + await expect(thingTypeToggle).toBeChecked({ checked: false }) + + await thingTypeToggle.click() + await expect(thingTypeToggle).toBeChecked({ checked: true }) + }) + + test("Open Basic TM and check for icon change in tab", async ({ page }) => { + await page.locator("#examples-btn").click() + + const thingTypeToggle = page.locator('#thing-type-btn') + await thingTypeToggle.click() + await expect(thingTypeToggle).toBeChecked({ checked: true }) + + const quickAccessBtn = page.locator(".example").filter({ hasText: 'Basic TM' }).nth(1).getByRole("button").nth(0) + await quickAccessBtn.click() + + const tabIcon = page.locator("#tab").nth(1).locator(".tab-icon") + await expect(tabIcon).toHaveText("TM") + }) + + test("Go to versioning in TD category and open example from quick access", async ({ page }) => { + await page.locator("#examples-btn").click() + + const categoryDropDown = page.locator("#thing-category") + await categoryDropDown.selectOption('9-versioning') + + const quickAccessBtn = page.locator(".example").filter({ hasText: 'Versioning' }).nth(0).getByRole("button").nth(0) + await quickAccessBtn.click() + + const exampleTab = page.locator("#tab").nth(1) + await expect(exampleTab).toHaveAttribute('data-tab-id', "2") + await expect(exampleTab).toHaveText("TDMyLampThingCloseCancel") + await expect(exampleTab).toHaveClass("active") + }) + + test("Go to Tm Optional in TM category and open example from quick access", async ({ page }) => { + await page.locator("#examples-btn").click() + + const thingTypeToggle = page.locator('#thing-type-btn') + await thingTypeToggle.click() + await expect(thingTypeToggle).toBeChecked({ checked: true }) + + const categoryDropDown = page.locator("#thing-category") + await categoryDropDown.selectOption('4-tm-optional') + + const quickAccessBtn = page.locator(".example").filter({ hasText: 'Optional Interaction Affordances' }).nth(0).getByRole("button").nth(0) + await quickAccessBtn.click() + + const exampleTab = page.locator("#tab").nth(1) + await expect(exampleTab).toHaveAttribute('data-tab-id', "2") + await expect(exampleTab).toHaveText("TMLamp ThingCloseCancel") + await expect(exampleTab).toHaveClass("active") + }) + + test("Search for uriVariable in the TDs and open Combined URI variables in href example", async ({ page }) => { + await page.locator("#examples-btn").click() + + const searchInput = page.locator(".search-input") + searchInput.fill('uriVariables') + + const searchBtn = page.locator(".search-btn") + await searchBtn.click() + + const quickAccessBtn = page.locator(".example").filter({ hasText: 'Combined URI variables in href' }).nth(0).getByRole("button").nth(0) + await quickAccessBtn.click() + + const exampleTab = page.locator("#tab").nth(1) + await expect(exampleTab).toHaveAttribute('data-tab-id', "2") + await expect(exampleTab).toHaveText("TDMyWeatherThingCloseCancel") + await expect(exampleTab).toHaveClass("active") + }) + + test("Search for overwrite in the TMs and open Overwrite Existing Definitions example", async ({ page }) => { + await page.locator("#examples-btn").click() + + const thingTypeToggle = page.locator('#thing-type-btn') + await thingTypeToggle.click() + await expect(thingTypeToggle).toBeChecked({ checked: true }) + + const searchInput = page.locator(".search-input") + searchInput.fill('overwrite') + + const searchBtn = page.locator(".search-btn") + await searchBtn.click() + + const quickAccessBtn = page.locator(".example").filter({ hasText: 'Overwrite Existing Definitions' }).nth(1).getByRole("button").nth(0) + await quickAccessBtn.click() + + const exampleTab = page.locator("#tab").nth(1) + await expect(exampleTab).toHaveAttribute('data-tab-id', "2") + await expect(exampleTab).toHaveText("TMSmart Lamp ControlCloseCancel") + await expect(exampleTab).toHaveClass("active") + }) +}) + +test.describe("Save menu functionality", () => { + test("Open and close save menu", async ({ page }) => { + const saveMenu = page.locator(".save-menu") + await expect(saveMenu).toHaveClass("save-menu closed") + + await page.locator("#save-btn").click() + await expect(saveMenu).toHaveClass("save-menu") + + const closeMenu = page.locator(".save-menu-close > i") + await closeMenu.click() + await expect(saveMenu).toHaveClass("save-menu closed") + }) + + test("Open save menu with template thing and check for TD in menu title", async ({ page }) => { + const saveMenu = page.locator(".save-menu") + + await page.locator("#save-btn").click() + await expect(saveMenu).toHaveClass("save-menu") + + const titleThingType = page.locator(".save-menu-title > p > #thing-type-text") + await expect(titleThingType).toHaveText("TD") + }) + + test("Open TM examples check for TM in the save menu title", async ({ page }) => { + await page.locator("#examples-btn").click() + + const thingTypeToggle = page.locator('#thing-type-btn') + await thingTypeToggle.click() + await expect(thingTypeToggle).toBeChecked({ checked: true }) + + const quickAccessBtn = page.locator(".example").filter({ hasText: 'Basic TM' }).nth(1).getByRole("button").nth(0) + await quickAccessBtn.click() + + const saveMenu = page.locator(".save-menu") + + await page.locator("#save-btn").click() + await expect(saveMenu).toHaveClass("save-menu") + + const titleThingType = page.locator(".save-menu-title > p > #thing-type-text") + await expect(titleThingType).toHaveText("TM") + }) + + test("Share and open in new tab functionality with an example", async ({ page }) => { + + await page.locator("#examples-btn").click() + + const basicExample = page.locator(".example").filter({ hasText: 'Basic TD' }).nth(0) + await expect(basicExample).toHaveClass("example") + + const quickAccessBtn = page.locator(".example").filter({ hasText: 'Basic TD' }).nth(0).getByRole("button").nth(0) + await quickAccessBtn.click() + + const exampleTab = page.locator("#tab").nth(1) + await expect(exampleTab).toHaveAttribute('data-tab-id', "2") + await expect(exampleTab).toHaveText("TDMyLampThingCloseCancel") + await expect(exampleTab).toHaveClass("active") + + const saveMenu = page.locator(".save-menu") + + await page.locator("#save-btn").click() + await expect(saveMenu).toHaveClass("save-menu") + + const openNewTab = page.locator("#open-url-tab") + await expect(openNewTab).toBeDisabled() + + const shareUrlInput = page.locator("#share-url-input") + await expect(shareUrlInput).toHaveText("") + + const shareUrlBtn = page.locator("#share-url-btn") + await shareUrlBtn.click() + + const newPlaygroundPromise = page.waitForEvent('popup') + await openNewTab.click() + const newPlaygroundPage = await newPlaygroundPromise + + await expect(newPlaygroundPage).toHaveTitle("TD Playground") + + const newPlaygroundTab = newPlaygroundPage.locator("#tab").nth(0) + await expect(newPlaygroundTab).toHaveAttribute('data-tab-id', "1") + await expect(newPlaygroundTab).toHaveText("TDMyLampThingCloseCancel") + await expect(newPlaygroundTab).toHaveClass("active") + + }) + + test("Open in ediTDor functionality", async ({ page }) => { + const saveMenu = page.locator(".save-menu") + + await page.locator("#save-btn").click() + await expect(saveMenu).toHaveClass("save-menu") + + const shareUrlInput = page.locator("#share-url-input") + await expect(shareUrlInput).toHaveText("") + + const openEditdorBtn = page.locator("#open-editdor-btn") + + const editdorPromise = page.waitForEvent('popup') + await openEditdorBtn.click() + const editdorPage = await editdorPromise + + await expect(editdorPage).toHaveTitle("ediTDor") + + const linkedTd = editdorPage.locator("#linkedTd > option") + await expect(linkedTd).toHaveText("Thing Template") + }) + + test("Download functionality", async ({ page }) => { + const saveMenu = page.locator(".save-menu") + + const exampleTab = page.locator("#tab").nth(0) + await expect(exampleTab).toHaveAttribute('data-tab-id', "1") + await expect(exampleTab).toHaveText("TDThing TemplateCloseCancel") + await expect(exampleTab).toHaveClass("active") + + await page.locator("#save-btn").click() + await expect(saveMenu).toHaveClass("save-menu") + + const downloadTdBtn = page.locator(".save-td__download") + + // Start waiting for download before clicking. + const downloadPromise = page.waitForEvent('download') + await downloadTdBtn.click() + const download = await downloadPromise + const expectedFilename = 'Thing-Template.json' + expect(download.suggestedFilename()).toBe(expectedFilename) + }) + + //* The "Save as" functionality cannot be tested because it requires to open and interact with the file system wich Playwright cannot do +}) + +test.describe("Settings menu functionality", () => { + test("Opening and closing the settings menu", async ({ page }) => { + const settingsMenu = page.locator(".settings-menu") + await expect(settingsMenu).toHaveClass("settings-menu closed") + + await page.locator("#settings-btn").click() + await expect(settingsMenu).toHaveClass("settings-menu") + + const closeMenu = page.locator(".settings__close > i") + await closeMenu.click() + await expect(settingsMenu).toHaveClass("settings-menu closed") + }) + + test("Checking settings toggle buttons", async ({ page }) => { + const settingsMenu = page.locator(".settings-menu") + await expect(settingsMenu).toHaveClass("settings-menu closed") + + await page.locator("#settings-btn").click() + await expect(settingsMenu).toHaveClass("settings-menu") + + const autoValidate = page.locator("#auto-validate") + const validateJsonld = page.locator("#validate-jsonld") + const tmConformance = page.locator("#tm-conformance") + + await expect(autoValidate).toBeChecked({ checked: false }) + await expect(validateJsonld).toBeChecked({ checked: true }) + await expect(tmConformance).toBeChecked({ checked: true }) + }) + + test("Changing page theme", async ({ page }) => { + const playgroundSite = page.locator("html") + await expect(playgroundSite).toHaveClass("light-mode") + + const settingsMenu = page.locator(".settings-menu") + await expect(settingsMenu).toHaveClass("settings-menu closed") + + await page.locator("#settings-btn").click() + await expect(settingsMenu).toHaveClass("settings-menu") + + const themePicker = page.locator("#theme-picker") + await themePicker.selectOption('monochrome-mode') + await expect(playgroundSite).toHaveClass("monochrome-mode") + + await themePicker.selectOption('dark-mode') + await expect(playgroundSite).toHaveClass("dark-mode") + + await page.reload({ waitUntil: 'domcontentloaded' }) + await expect(playgroundSite).toHaveClass("dark-mode") + }) + + test("Changing font size", async ({ page }) => { + const settingsMenu = page.locator(".settings-menu") + await expect(settingsMenu).toHaveClass("settings-menu closed") + + await page.locator("#settings-btn").click() + await expect(settingsMenu).toHaveClass("settings-menu") + + const editorFontSize = page.locator(".editor-font-size") + await expect(editorFontSize).toHaveText("14") + + const fontSizeSlider = page.locator('#font-size') + await fontSizeSlider.click() + + await expect(editorFontSize).toHaveText("23") + + await page.reload({ waitUntil: 'domcontentloaded' }) + + await expect(settingsMenu).toHaveClass("settings-menu closed") + + await page.locator("#settings-btn").click() + await expect(settingsMenu).toHaveClass("settings-menu") + + await expect(editorFontSize).toHaveText("23") + }) + + test("Utilizing default settings", async ({ page }) => { + const playgroundSite = page.locator("html") + await expect(playgroundSite).toHaveClass("light-mode") + + const settingsMenu = page.locator(".settings-menu") + await expect(settingsMenu).toHaveClass("settings-menu closed") + + await page.locator("#settings-btn").click() + await expect(settingsMenu).toHaveClass("settings-menu") + + const themePicker = page.locator("#theme-picker") + await themePicker.selectOption('dark-mode') + await expect(playgroundSite).toHaveClass("dark-mode") + + const editorFontSize = page.locator(".editor-font-size") + await expect(editorFontSize).toHaveText("14") + + const fontSizeSlider = page.locator('#font-size') + await fontSizeSlider.click() + + await expect(editorFontSize).toHaveText("23") + + await page.reload({ waitUntil: 'domcontentloaded' }) + + await expect(settingsMenu).toHaveClass("settings-menu closed") + + await page.locator("#settings-btn").click() + await expect(settingsMenu).toHaveClass("settings-menu") + + await expect(playgroundSite).toHaveClass("dark-mode") + await expect(editorFontSize).toHaveText("23") + + const resetSettings = page.locator('.reset-settings') + await resetSettings.click() + + await expect(playgroundSite).toHaveClass("light-mode") + await expect(editorFontSize).toHaveText("14") + + await page.reload({ waitUntil: 'domcontentloaded' }) + + await expect(settingsMenu).toHaveClass("settings-menu closed") + + await page.locator("#settings-btn").click() + await expect(settingsMenu).toHaveClass("settings-menu") + + await expect(playgroundSite).toHaveClass("light-mode") + await expect(editorFontSize).toHaveText("14") + }) +}) + +test.describe("Validation view functionality", () => { + + test("Starting the validation with the main valiation button", async ({ page }) => { + + const validationTab = page.locator('#validation-tab') + const validationView = page.locator('#validation-view') + + await expect(validationTab).toBeChecked() + await expect(validationView).toHaveClass("console-view validation-view") + + const stateIcon = page.locator(".json-validation-section > .section-header > i").nth(0) + await expect(stateIcon).toHaveClass("fa-solid fa-circle") + + const validationBtn = page.locator("#validate-btn") + await validationBtn.click() + + //TODO: Find a better way to wait for this event to happen + await page.waitForTimeout(5000) + await expect(stateIcon).toHaveClass("fa-solid fa-circle-check") + }) + + test("Closing the default validation view and opening it again with the validation view tab", async ({ page }) => { + + const validationTab = page.locator('#validation-tab') + const validationView = page.locator('#validation-view') + + await expect(validationTab).toBeChecked() + await expect(validationView).toHaveClass("console-view validation-view") + + const trashBtn = page.locator(".trash") + await trashBtn.click() + + await expect(validationTab).toBeChecked({checked: false}) + await expect(validationView).toHaveClass("console-view validation-view hidden") + + await validationTab.click() + + await expect(validationTab).toBeChecked({checked: true}) + await expect(validationView).toHaveClass("console-view validation-view") + + const stateIcon = page.locator(".json-validation-section > .section-header > i").nth(0) + await expect(stateIcon).toHaveClass("fa-solid fa-circle-check") + }) + + test("Validating the 'All Defaults TD'", async ({ page }) => { + const validationTab = page.locator('#validation-tab') + const validationView = page.locator('#validation-view') + + await expect(validationTab).toBeChecked() + await expect(validationView).toHaveClass("console-view validation-view") + + await page.locator("#examples-btn").click() + + const quickAccessBtn = page.locator(".example").filter({ hasText: 'All Default Values' }).getByRole("button").nth(0) + await quickAccessBtn.click() + + const exampleTab = page.locator("#tab").nth(1) + await expect(exampleTab).toHaveAttribute('data-tab-id', "2") + await expect(exampleTab).toHaveText("TDMyLampThingCloseCancel") + await expect(exampleTab).toHaveClass("active") + + await expect(validationTab).toBeChecked({checked: false}) + await expect(validationView).toHaveClass("console-view validation-view hidden") + + const validationBtn = page.locator("#validate-btn") + await validationBtn.click() + + await expect(validationTab).toBeChecked({checked: true}) + await expect(validationView).toHaveClass("console-view validation-view") + + //validation section + const jsonValidationSection = page.locator(".json-validation-section") + const jsonValidationSectionIcon = page.locator(".json-validation-section > .section-header > i").nth(0) + const jsonValidationSectionTxt = page.locator(".json-validation-section > .section-content > li") + + await jsonValidationSection.click() + await expect(jsonValidationSectionTxt).toHaveText("Validated Successfully") + await expect(jsonValidationSectionIcon).toHaveClass("fa-solid fa-circle-check") + + const jsonSchemaValidationSection = page.locator(".json-schema-validation-section") + const jsonSchemaValidationSectionIcon = page.locator(".json-schema-validation-section > .section-header > i").nth(0) + const jsonSchemaValidationSectionTxt = page.locator(".json-schema-validation-section > .section-content > li") + + await jsonSchemaValidationSection.click() + await expect(jsonSchemaValidationSectionTxt).toHaveText("Validated Successfully") + await expect(jsonSchemaValidationSectionIcon).toHaveClass("fa-solid fa-circle-check") + + const jsonSchemaDefaultsSection = page.locator(".json-schema-defaults-section") + const jsonSchemaDefaultsSectionIcon = page.locator(".json-schema-defaults-section > .section-header > i").nth(0) + const jsonSchemaDefaultsSectionTxt = page.locator(".json-schema-defaults-section > .section-content > li") + + await jsonSchemaDefaultsSection.click() + await expect(jsonSchemaDefaultsSectionTxt).toHaveText("Validated Successfully") + await expect(jsonSchemaDefaultsSectionIcon).toHaveClass("fa-solid fa-circle-check") + + const jsonlsValidationSection = page.locator(".jsonls-validation-section") + const jsonlsValidationSectionIcon = page.locator(".jsonls-validation-section > .section-header > i").nth(0) + const jsonlsValidationSectionTxt = page.locator(".jsonls-validation-section > .section-content > li") + + await jsonlsValidationSection.click() + await expect(jsonlsValidationSectionTxt).toHaveText("Validated Successfully") + await expect(jsonlsValidationSectionIcon).toHaveClass("fa-solid fa-circle-check") + + const additionalChecksSection = page.locator(".additional-checks-section") + const additionalChecksSectionIcon = page.locator(".additional-checks-section > .section-header > i").nth(0) + const additionalChecksSectionTxt = page.locator(".additional-checks-section > .section-content > li") + + await additionalChecksSection.click() + await expect(additionalChecksSectionTxt).toHaveText("Validated Successfully") + await expect(additionalChecksSectionIcon).toHaveClass("fa-solid fa-circle-check") + }) + + test("Validating the 'Basic TD'", async ({ page }) => { + const validationTab = page.locator('#validation-tab') + const validationView = page.locator('#validation-view') + + await expect(validationTab).toBeChecked() + await expect(validationView).toHaveClass("console-view validation-view") + + await page.locator("#examples-btn").click() + + const quickAccessBtn = page.locator(".example").filter({ hasText: 'Basic TD' }).getByRole("button").nth(0) + await quickAccessBtn.click() + + const exampleTab = page.locator("#tab").nth(1) + await expect(exampleTab).toHaveAttribute('data-tab-id', "2") + await expect(exampleTab).toHaveText("TDMyLampThingCloseCancel") + await expect(exampleTab).toHaveClass("active") + + await expect(validationTab).toBeChecked({checked: false}) + await expect(validationView).toHaveClass("console-view validation-view hidden") + + const validationBtn = page.locator("#validate-btn") + await validationBtn.click() + + await expect(validationTab).toBeChecked({checked: true}) + await expect(validationView).toHaveClass("console-view validation-view") + + + //Validation section + const jsonValidationSection = page.locator(".json-validation-section") + const jsonValidationSectionIcon = page.locator(".json-validation-section > .section-header > i").nth(0) + const jsonValidationSectionTxt = page.locator(".json-validation-section > .section-content > li") + + await jsonValidationSection.click() + await expect(jsonValidationSectionTxt).toHaveText("Validated Successfully") + await expect(jsonValidationSectionIcon).toHaveClass("fa-solid fa-circle-check") + + const jsonSchemaValidationSection = page.locator(".json-schema-validation-section") + const jsonSchemaValidationSectionIcon = page.locator(".json-schema-validation-section > .section-header > i").nth(0) + const jsonSchemaValidationSectionTxt = page.locator(".json-schema-validation-section > .section-content > li") + + await jsonSchemaValidationSection.click() + await expect(jsonSchemaValidationSectionTxt).toHaveText("Validated Successfully") + await expect(jsonSchemaValidationSectionIcon).toHaveClass("fa-solid fa-circle-check") + + const jsonSchemaDefaultsSection = page.locator(".json-schema-defaults-section") + const jsonSchemaDefaultsSectionIcon = page.locator(".json-schema-defaults-section > .section-header > i").nth(0) + const jsonSchemaDefaultsSectionTxt = page.locator(".json-schema-defaults-section > .section-content > li").nth(0) + + await jsonSchemaDefaultsSection.click() + await expect(jsonSchemaDefaultsSectionTxt).toHaveText("Optional validation failed:") + await expect(jsonSchemaDefaultsSectionIcon).toHaveClass("fa-solid fa-circle-exclamation") + + const jsonlsValidationSection = page.locator(".jsonls-validation-section") + const jsonlsValidationSectionIcon = page.locator(".jsonls-validation-section > .section-header > i").nth(0) + const jsonlsValidationSectionTxt = page.locator(".jsonls-validation-section > .section-content > li") + + await jsonlsValidationSection.click() + await expect(jsonlsValidationSectionTxt).toHaveText("Validated Successfully") + await expect(jsonlsValidationSectionIcon).toHaveClass("fa-solid fa-circle-check") + + const additionalChecksSection = page.locator(".additional-checks-section") + const additionalChecksSectionIcon = page.locator(".additional-checks-section > .section-header > i").nth(0) + const additionalChecksSectionTxt = page.locator(".additional-checks-section > .section-content > li") + + await additionalChecksSection.click() + await expect(additionalChecksSectionTxt).toHaveText("Validated Successfully") + await expect(additionalChecksSectionIcon).toHaveClass("fa-solid fa-circle-check") + }) + + test("Validating the 'Basic TM'", async ({ page }) => { + + const validationTab = page.locator('#validation-tab') + const validationView = page.locator('#validation-view') + + await expect(validationTab).toBeChecked() + await expect(validationView).toHaveClass("console-view validation-view") + + await page.locator("#examples-btn").click() + + const thingTypeToggle = page.locator('#thing-type-btn') + await thingTypeToggle.click() + await expect(thingTypeToggle).toBeChecked({ checked: true }) + + const quickAccessBtn = page.locator(".example").filter({ hasText: 'Basic TM' }).nth(1).getByRole("button").nth(0) + await quickAccessBtn.click() + + const exampleTab = page.locator("#tab").nth(1) + await expect(exampleTab).toHaveAttribute('data-tab-id', "2") + await expect(exampleTab).toHaveText("TMLamp ThingCloseCancel") + await expect(exampleTab).toHaveClass("active") + + await expect(validationTab).toBeChecked({checked: false}) + await expect(validationView).toHaveClass("console-view validation-view hidden") + + const validationBtn = page.locator("#validate-btn") + await validationBtn.click() + + await expect(validationTab).toBeChecked({checked: true}) + await expect(validationView).toHaveClass("console-view validation-view") + + //Validation section + const jsonValidationSection = page.locator(".json-validation-section") + const jsonValidationSectionIcon = page.locator(".json-validation-section > .section-header > i").nth(0) + const jsonValidationSectionTxt = page.locator(".json-validation-section > .section-content > li") + + await jsonValidationSection.click() + await expect(jsonValidationSectionTxt).toHaveText("Validated Successfully") + await expect(jsonValidationSectionIcon).toHaveClass("fa-solid fa-circle-check") + + const jsonSchemaValidationSection = page.locator(".json-schema-validation-section") + const jsonSchemaValidationSectionIcon = page.locator(".json-schema-validation-section > .section-header > i").nth(0) + const jsonSchemaValidationSectionTxt = page.locator(".json-schema-validation-section > .section-content > li") + + await jsonSchemaValidationSection.click() + await expect(jsonSchemaValidationSectionTxt).toHaveText("Validated Successfully") + await expect(jsonSchemaValidationSectionIcon).toHaveClass("fa-solid fa-circle-check") + + const jsonSchemaDefaultsSection = page.locator(".json-schema-defaults-section") + const jsonSchemaDefaultsSectionIcon = page.locator(".json-schema-defaults-section > .section-header > i").nth(0) + const jsonSchemaDefaultsSectionTxt = page.locator(".json-schema-defaults-section > .section-content > li").nth(0) + + await jsonSchemaDefaultsSection.click() + await expect(jsonSchemaDefaultsSectionTxt).toHaveText("A previous validation has failed or it is only available for Thing Descriptions") + await expect(jsonSchemaDefaultsSectionIcon).toHaveClass("fa-solid fa-circle") + + const jsonlsValidationSection = page.locator(".jsonls-validation-section") + const jsonlsValidationSectionIcon = page.locator(".jsonls-validation-section > .section-header > i").nth(0) + const jsonlsValidationSectionTxt = page.locator(".jsonls-validation-section > .section-content > li") + + await jsonlsValidationSection.click() + await expect(jsonlsValidationSectionTxt).toHaveText("Validated Successfully") + await expect(jsonlsValidationSectionIcon).toHaveClass("fa-solid fa-circle-check") + + const additionalChecksSection = page.locator(".additional-checks-section") + const additionalChecksSectionIcon = page.locator(".additional-checks-section > .section-header > i").nth(0) + const additionalChecksSectionTxt = page.locator(".additional-checks-section > .section-content > li") + + await additionalChecksSection.click() + await expect(additionalChecksSectionTxt).toHaveText("Validated Successfully") + await expect(additionalChecksSectionIcon).toHaveClass("fa-solid fa-circle-check") + }) + +}) + + +/* +7. openapi +8. async api +9. aas conversion +10. defaults +11. visualize +*/ \ No newline at end of file