Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

カートページのテストを fixture を使用したものに変更 #534

Merged
merged 2 commits into from
Mar 30, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 24 additions & 1 deletion e2e-tests/pages/cart.page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,41 @@ import PlaywrightConfig from '../../playwright.config';

export class CartPage {
readonly page: Page;
readonly url: string;

readonly nextButton: Locator;

constructor(page: Page) {
this.page = page;
this.url = `${PlaywrightConfig.use.baseURL}/cart/index.php`;
this.nextButton = page.locator('input[name=confirm][alt=購入手続きへ]');
}

async goto() {
await this.page.goto(`${PlaywrightConfig.use.baseURL}/cart/index.php`);
await this.page.goto(this.url);
}

async gotoNext() {
await this.nextButton.click();
}

getAdditionButton(row?: number) {
return this.page.locator(`table[summary=商品情報] >> tr >> nth=${row ?? 1} >> td >> nth=4 >> [alt="+"]`);
}

getSubtructionButton(row?: number) {
return this.page.locator(`table[summary=商品情報] >> tr >> nth=${row ?? 1} >> td >> nth=4 >> [alt="-"]`);
}

getQuantity(row?: number) {
return this.page.locator(`table[summary=商品情報] >> tr >> nth=${row ?? 1} >> td >> nth=4`);
}

async addition(row?: number) {
await this.getAdditionButton(row).click();
}

async subtruction(row?: number) {
await this.getSubtructionButton(row).click();
}
}
171 changes: 71 additions & 100 deletions e2e-tests/test/front_login/cart/cart.test.ts
Original file line number Diff line number Diff line change
@@ -1,48 +1,30 @@
import { test, expect, chromium, Page } from '@playwright/test';
import { Page } from '@playwright/test';
import PlaywrightConfig from '../../../../playwright.config';
import { ZapClient, Mode, ContextType, Risk, HttpMessage } from '../../../utils/ZapClient';
import { ZapClient, ContextType, Risk } from '../../../utils/ZapClient';
import { intervalRepeater } from '../../../utils/Progress';
const zapClient = new ZapClient();

const url = `${PlaywrightConfig.use.baseURL}/cart/index.php`;
import { CartPage } from '../../../pages/cart.page';

// 商品をカートに入れて購入手続きへ進むフィクスチャ
import { test, expect } from '../../../fixtures/cartin.fixture';

test.describe.serial('カートページのテストをします', () => {
let page: Page;
test.beforeAll(async () => {
await zapClient.setMode(Mode.Protect);
await zapClient.newSession('/zap/wrk/sessions/front_login_cart', true);
await zapClient.importContext(ContextType.FrontLogin);

if (!await zapClient.isForcedUserModeEnabled()) {
await zapClient.setForcedUserModeEnabled();
expect(await zapClient.isForcedUserModeEnabled()).toBeTruthy();
}
const browser = await chromium.launch();
page = await browser.newPage();
await page.goto(url);
});

const detailURL = `${PlaywrightConfig.use.baseURL}/products/detail.php?product_id=1`;
test('商品詳細ページを表示します', async () => {
await page.goto(detailURL);
await expect(page.locator('#detailrightbloc > h2')).toContainText('アイスクリーム');
await zapClient.startSession(ContextType.FrontLogin, 'front_login_cart');
});

test('商品をカートに入れます', async () => {
await page.selectOption('select[name=classcategory_id1]', { label: '抹茶' });
await page.selectOption('select[name=classcategory_id2]', { label: 'S' });
await page.fill('input[name=quantity]', '2');
await page.click('[alt=カゴに入れる]');
});

test('カートの内容を確認します', async () => {
test('カートの内容を確認します', async ( { page } ) => {
const cartPage = new CartPage(page);
await cartPage.goto();
await expect(page.locator('h2.title')).toContainText('現在のカゴの中');
await expect(page.locator('table[summary=商品情報] >> tr >> nth=1')).toContainText('アイスクリーム');
});

test.describe('テストを実行します[GET] @attack', () => {
let scanId: number;
test('アクティブスキャンを実行します', async () => {
test('アクティブスキャンを実行します', async ( { page } ) => {
scanId = await zapClient.activeScanAsUser(url, 2, 110, false, null, 'GET');
await intervalRepeater(async () => await zapClient.getActiveScanStatus(scanId), 5000, page);
});
Expand All @@ -53,30 +35,30 @@ test.describe.serial('カートページのテストをします', () => {
});
});

test('カートの数量を加算します', async () => {
await page.reload();
const quantity = parseInt(await page.locator('table[summary=商品情報] >> tr >> nth=1 >> td >> nth=4').textContent());
await page.click('table[summary=商品情報] >> tr >> nth=1 >> td >> nth=4 >> [alt="+"]');
await expect(page.locator('table[summary=商品情報] >> tr >> nth=1 >> td >> nth=4')).toContainText(String(quantity + 1));
const getMessage = async (page: Page, additionParams: string) => {
const result = await zapClient.getMessages(url, await zapClient.getNumberOfMessages(url) - 1, 1);
const message = result.pop();
const transactionid = await page.locator('input[name=transactionid]').first().inputValue();
const requestBody = message.requestBody.replace(/transactionid=[a-z0-9]+/, `transactionid=${transactionid}`);
await zapClient.sendRequest(`${message.requestHeader}${requestBody}${additionParams}`);
return await zapClient.getLastMessage(url);
};

test('カートの数量を加算します', async ( { page } ) => {
const cartPage = new CartPage(page);
await cartPage.goto();
const quantity = parseInt(await cartPage.getQuantity().textContent());
await cartPage.addition();
await expect(cartPage.getQuantity()).toContainText(String(quantity + 1));
});

test.describe('数量加算のテストを実行します[POST] @attack', () => {

let message: HttpMessage;
let requestBody: string;
test('履歴を取得します', async () => {
const result = await zapClient.getMessages(url, await zapClient.getNumberOfMessages(url) - 1, 1);
message = result.pop();
expect(message.requestBody).toContain('mode=up');
});
test('transactionid を取得し直します', async () => {
await page.goto(url);
const transactionid = await page.locator('input[name=transactionid]').first().inputValue();
requestBody = message.requestBody.replace(/transactionid=[a-z0-9]+/, `transactionid=${transactionid}`);
});

let scanId: number;
test('アクティブスキャンを実行します', async () => {
test('アクティブスキャンを実行します', async ( { page } ) => {
const cartPage = new CartPage(page);
await cartPage.goto();
await cartPage.addition();
const requestBody = await getMessage(page, '&mode_up=dummy').then(httpMessage => httpMessage.requestBody);
expect(requestBody).toContain('mode=up');
scanId = await zapClient.activeScanAsUser(url, 2, 110, false, null, 'POST', requestBody);
await intervalRepeater(async () => await zapClient.getActiveScanStatus(scanId), 5000, page);
Expand All @@ -88,35 +70,50 @@ test.describe.serial('カートページのテストをします', () => {
});
});

test('カートの数量を減算します', async () => {
await page.reload();
const quantity = parseInt(await page.locator('table[summary=商品情報] >> tr >> nth=1 >> td >> nth=4').textContent());
await page.click('table[summary=商品情報] >> tr >> nth=1 >> td >> nth=4 >> [alt="-"]');
await expect(page.locator('table[summary=商品情報] >> tr >> nth=1 >> td >> nth=4')).toContainText(String(quantity - 1));
test('カートの数量を減算します', async ( { page } ) => {
const cartPage = new CartPage(page);
await cartPage.goto();
const quantity = parseInt(await cartPage.getQuantity().textContent());
await cartPage.subtruction();
await expect(cartPage.getQuantity()).toContainText(String(quantity - 1));
});

test.describe('数量減算のテストを実行します[POST] @attack', () => {

let message: HttpMessage;
let requestBody: string;
test('履歴を取得します', async () => {
const result = await zapClient.getMessages(url, await zapClient.getNumberOfMessages(url) - 1, 1);
message = result.pop();
});
test('transactionid を取得し直します', async () => {
await page.goto(url);
const transactionid = await page.locator('input[name=transactionid]').first().inputValue();
requestBody = message.requestBody.replace(/transactionid=[a-z0-9]+/, `transactionid=${transactionid}`);
});
let manuallyMessage: HttpMessage;
test('数量減算の requestBody に書き換えて手動送信します', async () => {
requestBody = requestBody.replace(/mode=down/, 'mode=down&mode_down=dummy');
await zapClient.sendRequest(message.requestHeader + requestBody);
manuallyMessage = await zapClient.getLastMessage(url);
});
let scanId: number;
test('アクティブスキャンを実行します', async () => {
expect(manuallyMessage.requestBody).toContain('mode=down');
test('アクティブスキャンを実行します', async ( { page } ) => {
const cartPage = new CartPage(page);
await cartPage.goto();
const transactionid = await page.locator('input[name=transactionid]').first().inputValue();
// JavaScript でカートの数量を増やしておく
await page.evaluate(async (transactionid: string) => {
await (async () => {
const searchParams = data => {
const params = new URLSearchParams();
Object.keys(data).forEach(key => params.append(key, data[key]));
return params;
};
const response = await fetch('/cart/index.php', {
method: 'POST',
cache: 'no-cache',
headers: {
'ContentType': 'application/x-www-form-urlencoded'
},
body: searchParams({
transactionid: transactionid,
mode: 'setQuantity',
quantity: '1000',
cart_no: '1',
cartKey: '1'
})
});

return response.body
})();
}, transactionid);

await cartPage.subtruction();
const requestBody = await getMessage(page, '&mode_down=dummy').then(httpMessage => httpMessage.requestBody);
expect(requestBody).toContain('mode=down');
scanId = await zapClient.activeScanAsUser(url, 2, 110, false, null, 'POST', requestBody);
await intervalRepeater(async () => await zapClient.getActiveScanStatus(scanId), 5000, page);
});
Expand All @@ -126,30 +123,4 @@ test.describe.serial('カートページのテストをします', () => {
.then(alerts => expect(alerts).toEqual([]));
});
});

test('購入手続きへ進みます', async () => {
await page.goto(url);
await page.click('input[name=confirm][alt=購入手続きへ]');
await expect(page.locator('h2.title')).toContainText('お届け先の指定');
});

test.describe('購入手続きへ進むテストを実行します[POST] @attack', () => {
let message: HttpMessage;
test('履歴を取得します', async () => {
message = await zapClient.getLastMessage(url);
expect(message.requestHeader).toContain(`POST ${url}`);
expect(message.responseHeader).toContain('HTTP/1.1 302 Found');
});

let scanId: number;
test('アクティブスキャンを実行します', async () => {
scanId = await zapClient.activeScanAsUser(url, 2, 110, false, null, 'POST', message.requestBody);
await intervalRepeater(async () => await zapClient.getActiveScanStatus(scanId), 5000, page);
});

test('結果を確認します', async () => {
await zapClient.getAlerts(url, 0, 1, Risk.High)
.then(alerts => expect(alerts).toEqual([]));
});
});
});