Ací es mostren les diferències entre la revisió seleccionada i la versió actual de la pàgina.
| Ambdós costats versió prèvia Revisió prèvia Següent revisió | Revisió prèvia | ||
|
nodejs_selenium [2024/01/22 20:03] enric_mieza_sanchez [Projecte base] |
nodejs_selenium [2025/02/04 18:36] (actual) enric_mieza_sanchez [Test 02 : login ok] |
||
|---|---|---|---|
| Línia 4: | Línia 4: | ||
| Ens pot ser molt pràctic per a realitzar tests per a [[Cordova]] o el propi [[NodeJS]]. | Ens pot ser molt pràctic per a realitzar tests per a [[Cordova]] o el propi [[NodeJS]]. | ||
| + | |||
| + | {{ selenium-diag.png }} | ||
| Referències: | Referències: | ||
| Línia 32: | Línia 34: | ||
| $ cd .test | $ cd .test | ||
| $ node 01-xxxx.js | $ node 01-xxxx.js | ||
| + | |||
| + | Per defecte s' | ||
| + | $ HEADLESS=false node 01-xxx.js | ||
| + | |||
| + | Per executar els tests amb Chrome enlloc de Firefox: | ||
| + | $ CHROME_TESTS=chrome node 01-xxx.js | ||
| + | |||
| + | \\ | ||
| ===== Projecte base ===== | ===== Projecte base ===== | ||
| Línia 45: | Línia 55: | ||
| │ | │ | ||
| └── .test | └── .test | ||
| - | ├── | + | ├── |
| └── 01-page-h1.js | └── 01-page-h1.js | ||
| Línia 55: | Línia 65: | ||
| \\ | \\ | ||
| - | ===== Desenvolupament en PHP ===== | + | ===== Desenvolupament |
| + | |||
| + | En aquests tests funcionals, els tests estan aïllats del desenvolupament i del llenguatge emprat, pel què podem fer un objecte per testejar qualsevol altre projecte. Només el fitxer '' | ||
| + | |||
| + | ==== Arxius de posada | ||
| + | |||
| + | <WRAP important> | ||
| + | '' | ||
| + | </ | ||
| + | |||
| + | |||
| + | <tabbox Versió Linux> | ||
| + | |||
| + | === run.sh per a PHP === | ||
| + | <file bash run.sh> | ||
| + | # | ||
| + | # directori del script run.sh | ||
| + | SCRIPT_DIR=$( cd -- "$( dirname -- " | ||
| + | # entrem a la carpeta del codi font | ||
| + | cd $SCRIPT_DIR/ | ||
| + | # engeguem el PHP server | ||
| + | php -S 0.0.0.0: | ||
| + | </ | ||
| + | |||
| + | === run.sh per a Cordova === | ||
| + | <file bash run.sh> | ||
| + | # | ||
| + | # directori del script run.sh | ||
| + | SCRIPT_DIR=$( cd -- "$( dirname -- " | ||
| + | # entrem a la carpeta del codi font | ||
| + | cd $SCRIPT_DIR | ||
| + | # engeguem el cordova sense browser | ||
| + | cordova serve | ||
| + | </ | ||
| + | |||
| + | <tabbox Versió Windows> | ||
| + | |||
| + | === run.sh per a Cordova | ||
| + | <file bash run.bat> | ||
| + | cordova serve | ||
| + | </ | ||
| + | |||
| + | </ | ||
| + | |||
| + | \\ | ||
| ==== Llibreria Base ==== | ==== Llibreria Base ==== | ||
| - | L' | ||
| - | <file javascript | + | <file javascript |
| const {Builder, Browser, By, Key, until} = require(" | const {Builder, Browser, By, Key, until} = require(" | ||
| const firefox = require(' | const firefox = require(' | ||
| Línia 68: | Línia 121: | ||
| - | class BasePhpTest | + | class BaseTest |
| constructor() { | constructor() { | ||
| Línia 83: | Línia 136: | ||
| // run server and setup driver | // run server and setup driver | ||
| - | await this.runServer( " | + | await this.runServer( " |
| await this.setupDriver(); | await this.setupDriver(); | ||
| // deixem temps a que el servidor es posi en marxa | // deixem temps a que el servidor es posi en marxa | ||
| Línia 90: | Línia 143: | ||
| async tearDown() { | async tearDown() { | ||
| - | console.log(" | + | console.log(" |
| // parem server | // parem server | ||
| await this.stopServer(); | await this.stopServer(); | ||
| Línia 117: | Línia 170: | ||
| let chromeOptions = new chrome.Options(); | let chromeOptions = new chrome.Options(); | ||
| if( this.headless ) { | if( this.headless ) { | ||
| - | console.log(" | + | console.log(" |
| - | firefoxOptions = new firefox.Options().headless(); | + | firefoxOptions = new firefox.Options().addArguments(' |
| chromeOptions = new chrome.Options().addArguments(' | chromeOptions = new chrome.Options().addArguments(' | ||
| } | } | ||
| Línia 137: | Línia 190: | ||
| // Engeguem server amb la APP | // Engeguem server amb la APP | ||
| if( process.platform==" | if( process.platform==" | ||
| - | this.cmd = spawn(command, | + | this.cmd = spawn(command+" |
| } else { | } else { | ||
| // linux, macos (darwin), or other | // linux, macos (darwin), or other | ||
| - | this.cmd = spawn(command, | + | this.cmd = spawn(command+" |
| } | } | ||
| Línia 169: | Línia 222: | ||
| } | } | ||
| - | // publiquem l' | + | // publiquem l' |
| - | exports.BasePhpTest | + | exports.BaseTest |
| </ | </ | ||
| Línia 179: | Línia 232: | ||
| <file javascript 01-header-h1.js> | <file javascript 01-header-h1.js> | ||
| // carreguem les llibreries | // carreguem les llibreries | ||
| - | const { BasePhpTest | + | const { BaseTest |
| const { By, until } = require(" | const { By, until } = require(" | ||
| const assert = require(' | const assert = require(' | ||
| Línia 186: | Línia 239: | ||
| // emprem this.driver per utilitzar Selenium | // emprem this.driver per utilitzar Selenium | ||
| - | class MyTest extends | + | class MyTest extends |
| { | { | ||
| async test() { | async test() { | ||
| // testejem H1 a la home page | // testejem H1 a la home page | ||
| ////////////////////////////////////////////////////// | ////////////////////////////////////////////////////// | ||
| - | await this.driver.get(" | + | await this.driver.get(" |
| - | var text = await this.driver.findElement(By.tagName(" | + | var currentText |
| - | + | var expectedText = " | |
| - | assert( | + | assert( |
| console.log(" | console.log(" | ||
| Línia 207: | Línia 260: | ||
| console.log(" | console.log(" | ||
| })(); | })(); | ||
| - | |||
| </ | </ | ||
| \\ | \\ | ||
| - | ==== Test 02 : formulari buit ==== | + | ==== Test 00 : formulari buit ==== |
| - | Aquest exemple testeja que si deixem buit el nom, ens surt un '' | + | Aquest exemple testeja que si deixem buit el nom, ens surt un '' |
| - | <file javascript | + | <file javascript |
| // carreguem les llibreries | // carreguem les llibreries | ||
| - | const { BasePhpTest | + | const { BaseTest |
| const { By, until } = require(" | const { By, until } = require(" | ||
| const assert = require(' | const assert = require(' | ||
| Línia 225: | Línia 277: | ||
| // emprem this.driver per utilitzar Selenium | // emprem this.driver per utilitzar Selenium | ||
| - | class MyTest extends | + | class MyTest extends |
| { | { | ||
| async test() { | async test() { | ||
| - | // testejem | + | // testejem |
| ////////////////////////////////////////////////////// | ////////////////////////////////////////////////////// | ||
| await this.driver.get(" | await this.driver.get(" | ||
| Línia 258: | Línia 310: | ||
| </ | </ | ||
| + | |||
| + | |||
| + | \\ | ||
| + | |||
| + | |||
| + | ==== Test 02 : login ok ==== | ||
| + | |||
| + | Testeja que podem logar-nos en un //admin panel// de [[Django]]. | ||
| + | |||
| + | <WRAP important> | ||
| + | És molt important **no deixar credencials en els arxius de codi** per raons òbvies. | ||
| + | |||
| + | Per selventar aquest problema, aquest exemple utilitza la llibreria '' | ||
| + | |||
| + | $ npm install dotenv | ||
| + | |||
| + | I crear un arxiu '' | ||
| + | URL=http:// | ||
| + | HEADLESS=false | ||
| + | USUARI=el-meu-username | ||
| + | CONTRASENYA=la-contrasenya-secreta | ||
| + | </ | ||
| + | |||
| + | <file javascript 02-login-ok.js> | ||
| + | |||
| + | // carreguem les llibreries | ||
| + | const { BaseTest } = require(" | ||
| + | const { By, until } = require(" | ||
| + | const assert = require(' | ||
| + | |||
| + | //.env | ||
| + | require(' | ||
| + | console.log(process.env) | ||
| + | |||
| + | class MyTest extends BaseTest | ||
| + | { | ||
| + | async test() { | ||
| + | // Login test | ||
| + | ////////////////////////////////////////////////////// | ||
| + | var site = process.env.URL | ||
| + | var driver = this.driver | ||
| + | await driver.get(site+"/ | ||
| + | |||
| + | // 1 cercar login box | ||
| + | let usernameInput = await driver.wait(until.elementLocated( | ||
| + | By.id(' | ||
| + | let passwordInput = await driver.wait(until.elementLocated( | ||
| + | By.id(' | ||
| + | |||
| + | // 2 posar usuari i pass | ||
| + | usernameInput.sendKeys(process.env.USUARI) | ||
| + | passwordInput.sendKeys(process.env.CONTRASENYA) | ||
| + | |||
| + | // 3 boto send .click() | ||
| + | let sendButton = await driver.wait(until.elementLocated( | ||
| + | By.css(' | ||
| + | sendButton.click() | ||
| + | |||
| + | // 4 comprovem que hem entrat | ||
| + | let logoutButton = await driver.wait(until.elementLocated( | ||
| + | By.xpath('// | ||
| + | var currentLogoutText = await logoutButton.getText(); | ||
| + | var expectedText = " | ||
| + | | ||
| + | // assert verifica que es compleixin condicions concretes | ||
| + | // si no es compleix, llançarà una excepció de test fallit | ||
| + | assert( currentLogoutText==expectedText, | ||
| + | "Login fallit.\n\tTEXT TROBAT=" | ||
| + | |||
| + | console.log(" | ||
| + | } | ||
| + | } | ||
| + | |||
| + | // executem el test | ||
| + | |||
| + | (async function test_example() { | ||
| + | const test = new MyTest(); | ||
| + | await test.run(); | ||
| + | console.log(" | ||
| + | })(); | ||
| + | </ | ||
| + | |||
| + | \\ | ||
| + | |||
| + | ==== Test Cordova : afegir tasca ==== | ||
| + | |||
| + | Aquest exemple inclou l'ús de prompts, que es fa com si fos un alert. | ||
| + | |||
| + | Fixeu-vos que Cordova necessita anar a la web ''/ | ||
| + | |||
| + | <file javascript addtask.js> | ||
| + | // carreguem les llibreries | ||
| + | const { BaseTest } = require(" | ||
| + | const { By, until } = require(" | ||
| + | const assert = require(' | ||
| + | |||
| + | // heredem una classe amb un sol mètode test() | ||
| + | // emprem this.driver per utilitzar Selenium | ||
| + | |||
| + | class AddTaskTest extends BaseTest | ||
| + | { | ||
| + | async test() { | ||
| + | // testejem afegir tasca en tasklist de Cordova | ||
| + | ////////////////////////////////////////////////////// | ||
| + | await this.driver.get(" | ||
| + | |||
| + | // cliquem botó " | ||
| + | await this.driver.findElement(By.xpath("// | ||
| + | |||
| + | // el prompt pel text de la tasca es tracta igual que un alert en Selenium | ||
| + | await this.driver.wait(until.alertIsPresent(), | ||
| + | let prompt = await this.driver.switchTo().alert(); | ||
| + | // afegim el text de la tasca i acceptem | ||
| + | var taskText = " | ||
| + | prompt.sendKeys(taskText); | ||
| + | await this.driver.sleep(1000); | ||
| + | await prompt.accept(); | ||
| + | await this.driver.sleep(1000); | ||
| + | |||
| + | // checkejem tasca | ||
| + | await this.driver.findElement(By.xpath("// | ||
| + | |||
| + | console.log(" | ||
| + | } | ||
| + | } | ||
| + | |||
| + | // executem el test | ||
| + | |||
| + | (async function test_example() { | ||
| + | const test = new AddTaskTest(); | ||
| + | await test.run(); | ||
| + | console.log(" | ||
| + | })(); | ||
| + | </ | ||
| + | |||
| + | <WRAP todo> | ||
| + | Crea un test '' | ||
| + | * Crei 3 tasques amb noms aleatoris. | ||
| + | * Esborri una d' | ||
| + | * Comprovi que no existeix la tasca esborrada i sí que romanen les altres dues. | ||
| + | </ | ||
| + | |||
| + | ===== Exercicis ===== | ||
| + | <WRAP todo> | ||
| + | Crea els següents tests amb la web que t'ha proporcionat el professor: | ||
| + | * 01 comprovar header h1 | ||
| + | * 02a fer login amb l' | ||
| + | * 02b intentar login amb usuari incorrecte (ha de refusar el login) | ||
| + | * 03 entrar i crear un llibre amb el teu nom | ||
| + | * 04 entrar i esborrar el llibre amb el teu nom. | ||
| + | * 05 crear un arbre de categories aniuades (jerarquia). Podeu triar temàtica: | ||
| + | * pelis: drama, thriller, acció, etc. | ||
| + | * productes: ferreteria, imatge i so, verdures, informàtica, | ||
| + | * regions: espanya, comunitat autònoma, província, ciutat | ||
| + | * regions2: continents, paisos, regions | ||
| + | * etc. | ||
| + | * 06 crear un llibre i cercar les dades per ISBN | ||
| + | </ | ||
| + | |||
| + | <WRAP todo> | ||
| + | Crea un dels següents tests que t' | ||
| + | [[Django Test # | ||
| + | </ | ||
| + | |||