From 018edfebbf6028938d9f942deb9fcb56041994df Mon Sep 17 00:00:00 2001 From: Vlad Smykov Date: Wed, 28 Jan 2026 16:39:23 +0300 Subject: [PATCH] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8=D0=BB=20?= =?UTF-8?q?=D0=BF=D0=BE=D0=B7=D0=B8=D1=82=D0=B8=D0=B2=D0=BD=D1=8B=D0=B5=20?= =?UTF-8?q?=D1=81=D1=86=D0=B5=D0=BD=D0=B0=D1=80=D0=B8=D0=B8=20=D0=B4=D0=BB?= =?UTF-8?q?=D1=8F=20UI,=20API=20=D1=80=D0=B5=D0=B3=D0=B8=D1=81=D1=82=D1=80?= =?UTF-8?q?=D0=B0=D1=86=D0=B8=D0=B8=20=D0=BE=D1=80=D0=B3=D0=B0=D0=BD=D0=B8?= =?UTF-8?q?=D0=B7=D0=B0=D1=86=D0=B8=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- page-objects/RegisterPage.ts | 72 +++++++++++++-- playwright.config.ts | 7 +- .../register-organization.api.spec.ts | 81 +++++++++++++++++ .../ui/registration/register-graduate.spec.ts | 4 +- .../register-organization.spec.ts | 90 +++++++++++++++++++ utils/userGenerator.ts | 16 ++++ 6 files changed, 259 insertions(+), 11 deletions(-) create mode 100644 tests/api/registration/register-organization.api.spec.ts create mode 100644 tests/ui/registration/register-organization.spec.ts diff --git a/page-objects/RegisterPage.ts b/page-objects/RegisterPage.ts index f479184..c5e047a 100644 --- a/page-objects/RegisterPage.ts +++ b/page-objects/RegisterPage.ts @@ -51,10 +51,14 @@ export class RegisterPage { } async clickNextButton() { - await this.page.locator('button[type="submit"]', { hasText: 'Далее' }).click(); + await this.page.locator('button[type="submit"]', { hasText: 'Далее' }).first().click(); } - async submitGraduate() { + async clickNextButtonOrg() { + await this.page.locator('button[type="submit"]', { hasText: 'Далее' }).last().click(); + } + + async submitGeneral() { await this.page.locator('button[type="submit"]', { hasText: 'Зарегистрироваться' }).click(); } @@ -62,10 +66,9 @@ export class RegisterPage { await this.page.locator('button[data-testid="btn-save"]').click(); } - // --- Этап 2: Образование выпускника --- - async selectGraduateRole() { - await this.page.locator('button.Registration_button_menu__AfPox', { hasText: 'Выпускник' }).click(); - } + async selectRole(roleName: 'Абитуриент' | 'Выпускник' | 'Организация') { + await this.page.getByRole('button', { name: roleName }).click(); +} async selectDepartment() { await this.page.locator('input[name="department"]').click(); @@ -93,4 +96,61 @@ export class RegisterPage { await this.page.locator('input[name="educationForm"]').click(); await this.page.getByText('Очная', { exact: true }).click(); } + +//Для организации + + async fillShortName(shortName: string) { + await this.page.fill('input[name="shortName"]', shortName); + } + + async fillFullName(fullName: string){ + await this.page.fill('input[name="fullName"]', fullName); + } + + async fillAddress(address: string) { +await this.page.fill('input[name="address"]', address); +} + + async fillKPP(kpp: string) { + await this.page.fill('input[name="kpp"]', kpp); +} + + async fillINN(inn: string) { + await this.page.fill('input[name="inn"]', inn); +} + + async fillSite(site: string) { + await this.page.fill('input[name="site"]', site); +} + + async fillDescription(description: string) { + await this.page.fill('textarea[name="description"]', description); +} + +// Step 3 + async fillDirectorFIO(fio: string) { + await this.page.fill('input[name="directorFIO"]', fio); +} + + async fillPosition(position: string) { + await this.page.fill('input[name="position"]', position); +} + + async fillBasis(basis: string) { + await this.page.fill('input[name="basis"]', basis); +} + + async fillTelegram(tg: string) { + await this.page.fill('input[name="tg"]', tg); +} + + async fillVK(vk: string) { + await this.page.fill('input[name="vk"]', vk); +} + + async expectSuccessModal() { + await this.page.getByRole('heading', { name: 'Ваши данные отправлены на проверку!' }).waitFor(); + await this.page.getByRole('button', { name: 'На главную' }).click(); +} + } diff --git a/playwright.config.ts b/playwright.config.ts index 5ddd4d8..70b3ed9 100644 --- a/playwright.config.ts +++ b/playwright.config.ts @@ -2,7 +2,7 @@ import { defineConfig } from '@playwright/test'; export default defineConfig({ testDir: './tests', - timeout: 30000, + timeout: 60000, expect: { timeout: 5000 }, @@ -14,12 +14,13 @@ export default defineConfig({ use: { headless: false, launchOptions: { - slowMo: 300, + slowMo: 900, }, viewport: { width: 1280, height: 720 }, ignoreHTTPSErrors: true, screenshot: 'only-on-failure', video: 'retain-on-failure', baseURL: 'https://rumc.dev.rdcenter.ru' - } + }, + workers: 1 }); diff --git a/tests/api/registration/register-organization.api.spec.ts b/tests/api/registration/register-organization.api.spec.ts new file mode 100644 index 0000000..7d8a028 --- /dev/null +++ b/tests/api/registration/register-organization.api.spec.ts @@ -0,0 +1,81 @@ +import { test, expect } from '@playwright/test'; +import axios from 'axios'; +import { + createTempEmail, + waitForConfirmationCode +} from '../../../utils/mailTmApi'; +import { + generateFirstName, + generateLastName, + generateMiddleName, + generateLogin, + generatePhone, + generateKPP, + generateINN, + generateShortOrgName, + generateFullOrgName +} from '../../../utils/userGenerator'; + +const BASE_URL = 'https://rumc.dev.rdcenter.ru/api'; + +test('API: регистрация организации + подтверждение почты', async () => { + const { email, token: mailToken } = await createTempEmail(); + + const surname = generateLastName(); + const name = generateFirstName(); + const patronymic = generateMiddleName(); + const representativeName = `${surname} ${name} ${patronymic}`; + const login = generateLogin(); + const phone = '+7 (900) 000-00-00'; + const password = '!Test123456'; + const shortName = generateShortOrgName(); + const fullName = generateFullOrgName(); + const kpp = generateKPP(); + const inn = generateINN(); + + const registerPayload = { + shortName, + fullName, + description: "Абсолютно неуникальное тестовое описание", + website: "https://test-org.ru", + address: "г. Таганрог, ул. Тестовая, д. 1", + inn, + kpp, + representativeName, + position: "Генеральный директор", + phone, + basis: "федерального закона", + email, + password, + login, + socialLinks: { + tg: "https://t.me/test_user", + vk: "https://vk.com/test_user" + }}; + + try { + const registerRes = await axios.post(`${BASE_URL}/auth/register/organization`, registerPayload); + expect(registerRes.status).toBe(200); + + const userId = registerRes.data.userId; + console.log('🆔 ID зарегистрированного пользователя:', userId); + +} catch (error: any) { + console.error('❌ Ошибка регистрации:', error.response?.data || error.message); + throw error; +} + + console.log('📬 Ожидание письма с кодом подтверждения...'); + const code = await waitForConfirmationCode(mailToken, 60000); + console.log('✅ Код получен:', code); + + const confirmPayload = { + email, + code + }; + + const confirmRes = await axios.post(`${BASE_URL}/auth/confirm`, confirmPayload); + expect(confirmRes.status).toBe(200); + + console.log('🎉 Почта подтверждена успешно'); +}); diff --git a/tests/ui/registration/register-graduate.spec.ts b/tests/ui/registration/register-graduate.spec.ts index d10cd5a..f733367 100644 --- a/tests/ui/registration/register-graduate.spec.ts +++ b/tests/ui/registration/register-graduate.spec.ts @@ -22,7 +22,7 @@ test('Полная регистрация выпускника с подтвер const registerPage = new RegisterPage(page); await registerPage.goto(); - await registerPage.selectGraduateRole(); + await registerPage.selectRole('Выпускник'); // Заполняем 1 этап регистрации await registerPage.fillLastName(lastName); @@ -42,7 +42,7 @@ test('Полная регистрация выпускника с подтвер await registerPage.selectProgram(); await registerPage.selectEducationForm(); await registerPage.checkConsentCheckbox(); - await registerPage.submitGraduate(); + await registerPage.submitGeneral(); await page.waitForTimeout(5000); await expect(page).toHaveURL(/confirmation-code/); diff --git a/tests/ui/registration/register-organization.spec.ts b/tests/ui/registration/register-organization.spec.ts new file mode 100644 index 0000000..a68c3c9 --- /dev/null +++ b/tests/ui/registration/register-organization.spec.ts @@ -0,0 +1,90 @@ +// Позитивный тест регистрации организации +// Включает в себя: +// Ввод валидных тестовых данных +// Получение кода в письме +// Ввод кода из письма (is_confirm) +// Переход на главную (через модальное окно) + +import { test, expect } from '@playwright/test'; +import { RegisterPage } from '../../../page-objects/RegisterPage'; +import { + generateFirstName, + generateLastName, + generateMiddleName, + generateLogin, + generatePhone, + generateKPP, + generateINN, + generateShortOrgName, + generateFullOrgName +} from '../../../utils/userGenerator'; +import { + createTempEmail, + waitForConfirmationCode +} from '../../../utils/mailTmApi'; + +test('Полная регистрация организации с подтверждением почты', async ({ page }) => { + const registerPage = new RegisterPage(page); + + const { email, token } = await createTempEmail(); + + const surname = generateLastName(); + const name = generateFirstName(); + const patronymic = generateMiddleName(); + const directorFIO = `${surname} ${name} ${patronymic}`; + const login = generateLogin(); + const phone = generatePhone(); + const password = '!Test123456'; + const shortName = generateShortOrgName(); + const fullName = generateFullOrgName(); + const address = 'г. Таганрог, ул. Тестовая, д. 1'; + const kpp = generateKPP(); + const inn = generateINN(); + const site = 'https://test-org.ru'; + const description = 'Абсолютно неуникальное тестовое описание'; + const position = 'Генеральный директор'; + const basis = 'закона'; + const tg = 'https://t.me/test_user'; + const vk = 'https://vk.com/test_user'; + + await registerPage.goto(); + await registerPage.selectRole('Организация'); + + //Первый этап регистраци + await registerPage.fillLogin(login); + await registerPage.fillEmail(email); + await registerPage.fillPassword(password); + await registerPage.fillPasswordRepeat(password); + await registerPage.clickNextButton(); + + //Второй этап регистрации + await registerPage.fillShortName(shortName); + await registerPage.fillFullName(fullName); + await registerPage.fillAddress(address); + await registerPage.fillKPP(kpp); + await registerPage.fillINN(inn); + await registerPage.fillSite(site); + await registerPage.fillPhone(phone); + await registerPage.fillDescription(description); + await registerPage.clickNextButtonOrg(); + + //Третий этап регистрации + await registerPage.fillDirectorFIO(directorFIO); + await registerPage.fillPosition(position); + await registerPage.fillBasis(basis); + await registerPage.fillTelegram(tg); + await registerPage.fillVK(vk); + await registerPage.checkConsentCheckbox(); + await registerPage.submitGeneral(); + + await expect(page).toHaveURL(/confirmation-code/); + const code = await waitForConfirmationCode(token, 60000); + + await page.fill('input[name="code"]', code); + await page.click('button.RecoverPassword_button__5QDxM'); + + await registerPage.expectSuccessModal(); + + await expect(page).toHaveURL('https://rumc.dev.rdcenter.ru'); + +}); diff --git a/utils/userGenerator.ts b/utils/userGenerator.ts index 04a2e69..0f05c5f 100644 --- a/utils/userGenerator.ts +++ b/utils/userGenerator.ts @@ -43,3 +43,19 @@ export function generatePhone(): string { const random = Math.floor(100000000 + Math.random() * 900000000); // 9 цифр return `+790${random}`; // +79012345678 } + +export function generateShortOrgName(): string { + return `Организация_${generateRandomString(3)}`; +} + +export function generateFullOrgName(): string { + return `ООО Организация_${generateRandomString(3)}`; +} + +export function generateKPP(): string { + return Array.from({ length: 9 }, () => Math.floor(Math.random() * 10)).join(""); +} + +export function generateINN(): string { + return Array.from({ length: 10 }, () => Math.floor(Math.random() * 10)).join(""); +} \ No newline at end of file