構成
Qmonus Lab環境でFrontTesterを利用する際に必要なディレクトリ構成について説明します。
ディレクトリ構成
Qmonus SDK Lab v3以降、ApiFrontのGitリポジトリに格納することを推奨しています。
また、リポジトリ内では下記のディレクトリ構成を標準としています。
各試験シナリオには、index.jsonと試験jsファイルの存在が必須となります。
/{ApiFront Repo} │ └─ /e2e_test (*default test scenarios directory) ├─ / your_test_scenarios01 │ │ index.json ## required 'index.json'! │ │ _login.js │ │ your_test_01.js │ │ your_test_02.js │ └─/util _util.js ## Files beginning with '_' are not read │ └─ /your_test_dir_name02 ...
重要
各試験シナリオは直下の階層にindex.jsonを持つことを前提としています。
SDK Portalから実行する場合、index.jsonがないと試験シナリオと認識しないため注意してください。
💡 Tips 試験シナリオと試験パラメータについて
FrontTesterでは
- 試験ファイル(hogehoge.js):ユーザのGUI操作を記述
- 試験パラメータ(index.json):試験時の入力値や試験判定フラグ、試験環境条件を記述
のように試験シナリオと試験データの分離を実現しています。
これによって、同一ページで行う複数の試験項目に対して同一のシナリオを使い回すことで、試験の柔軟性が上がり、GUI改修時のメンテナンスや試験項目追加時の稼働の削減を実現します。
例:
登録画面に対して正常形と2つの準正常系の試験を作る際、
通常試験では
- postPage_success.js - postPage_guiValid.js - postPage_apiValid.js
の3つのページを作成することに対してFrontTesterでは、
- postPage.js - index.json ## index.jsonの中身 (中略) "create": [ { ## sucess パターン "expect_successed": true, "expect_gui_validation": false, "expect_api_validation": false, ... }, { ## gui valid パターン "expect_successed": false, "expect_gui_validation": true, "expect_api_validation": false, ... }, { ## api valid パターン "expect_successed": false, "expect_gui_validation": false, "expect_api_validation": true, ... }, ],
とすることで、1シナリオファイル + 各試験目的パラメータの形式を取るように設計が可能になる。
ファイルについて
FrontTesterを実行する際の必須ファイルについて説明します。
試験パラメータファイル [ index.json ]
下記サンプルの内容はSDK PortalのFrontTesterのGUIからindex.jsonを作成するとデフォルトで用意されます。
パラメータに関しては試験パラメータを参考に作成してください。
index.json { "description": "", "paramSchema": { "type": "object", "properties": {} }, "params": { "user": "test_user", "password": "hogehoge" }, "defaultOptions": { "lang": "en-US", "viewport": { "width": 1366, "height": 768, }, "headless": false, "devtools": false, "autoSnapshot": false, "snapshotQuality": 10, "frameSelector": "casval-content-main" } }
試験ファイル [xx_xx.js]
- ファイルはアルファベット順で実行されます
- ファイル名の先頭に_をつけると、その試験ファイルは試験対象外としてスキップします。
/** * 1) how to use playwright. * * // page load * await page.goto( '[URL]' ) * * // set timeout * page.setDefaultNavigationTimeout( 60000 ) * page.setDefaultTimeout( 60000 ) * * // page action * let obj = await root.locator( '[SELECTOR STRING]' ) * await obj.hover() * await obj.focus() * await obj.click() * await obj.type('[INPUT VALUE]') * * // Wait For * await page.waitForNavigation({timeout: 60000, waitUntil: "domcontentloaded"}) * await root.waitForSelector('[SELECTOR STRING]') * await root.waitForTimeout(300) * * => See 'https://playwright.dev/' for details * * 2) Utility Actions ( Wrapped Methods by SDK Portal ) * * // save screenshot * await actions.screenshot( '[DESCRIPTION STRING]' ) * * // save resultCache * await actions.saveResults( '[JSON KEY]' , '[JSON VALUE]' ) * * // get resultCache * actions.getResults() * * // output log * await actions.logger( '[LOG MESSAGE]', '[LOG LEVEL]') * * // get running scenario file path * await actions.getFilePath() * * // get root frame * await actions.getRoot() * * // get evidence dirctory path * actions.getEvidenceDir() */ module.exports = async ( { params , root , page , actions } )=>{ // page move await page.goto( params.url ) // set timeouts page.setDefaultNavigationTimeout( params.timeout ) page.setDefaultTimeout( params.timeout ) // screenshot await actions.screenshot( "first cap" ) // logging await actions.logger("first log" , "DEBUG" ) // redirect page check let url = page.url() if( url.indexOf( params.login_page ) < 0 ) throw new Error("Redirect Error!!!!") // login await page.type("#username" , params.login_user , {delay:10} ) await page.type("#password" , params.login_pass , {delay:10} ) // Submit and wait page load await Promise.all([ page.waitForNavigation(), page.click("input[type=submit", {delay:100, clickCount:1}) ]) await actions.screenshot( 'log in!' ) // wait for progress complete await root.waitForSelector('#progress', [state:detached]) }
4.試験パラメータ
2.基本操作説明