from playwright.sync_api import expect from .base import BasePage class ReceiptUploadPage(BasePage): def control_transport(self): """Pause the browser transport while keeping the final POST real.""" self.page.add_init_script("""(() => { const Native = window.XMLHttpRequest; window.receiptTransport = {count: 0}; window.XMLHttpRequest = class extends Native { open(method, url, ...rest) { this.receiptRequest = method === 'POST' && /payment-receipt|receipts/.test(url); super.open(method, url, ...rest); } send(payload) { if (!this.receiptRequest) return super.send(payload); window.receiptTransport.count++; window.receiptTransport.current = this; this.release = () => super.send(payload); this.upload.dispatchEvent(new ProgressEvent('progress', { lengthComputable: true, loaded: 524288, total: 1048576 })); } }; })();""") def fill_receipt(self, account_id, png): self.page.locator('#id_paid_amount').fill('۱۲۳۴۵') self.page.locator('#id_destination_account').select_option(str(account_id)) self.page.get_by_role('button', name='امروز', exact=True).click() self.page.locator('#id_receipt_image').set_input_files({'name': 'receipt.png', 'mimeType': 'image/png', 'buffer': png}) def submit(self): self.page.get_by_role('button', name='ثبت و ارسال فیش', exact=True).click() def assert_uploading(self): expect(self.page.locator('#receipt-upload')).to_be_visible() expect(self.page.locator('#receipt-upload-percent')).to_have_text('۵۰٪') expect(self.page.locator('#receipt-upload-bytes')).to_have_text('ارسال‌شده: ۵۱۲ کیلوبایت از ۱ مگابایت') expect(self.page.locator('#receipt-upload-time')).to_contain_text('دیگر برای ارسال') expect(self.page.locator('#submit-receipt')).to_be_disabled() expect(self.page.locator('#id_receipt_image')).to_be_disabled() def repeat_submission(self): self.page.locator('#receipt-form').evaluate("form => {form.requestSubmit(); form.requestSubmit();}") assert self.page.evaluate('window.receiptTransport.count') == 1 def processing(self): self.page.evaluate("window.receiptTransport.current.upload.dispatchEvent(new Event('load'))") expect(self.page.locator('#receipt-upload-percent')).to_have_text('۱۰۰٪') expect(self.page.locator('#receipt-upload-title')).to_contain_text('در حال بررسی و ثبت فیش') expect(self.page.locator('#submit-receipt')).to_be_disabled() def fail_network(self): self.page.evaluate("window.receiptTransport.current.dispatchEvent(new Event('error'))") expect(self.page.locator('#receipt-errors')).to_contain_text('ارتباط با سرور قطع شد') expect(self.page.locator('#submit-receipt')).to_be_enabled() expect(self.page.locator('#id_receipt_image')).to_be_enabled() assert self.page.locator('#id_receipt_image').evaluate('input => input.files.length') == 1 def reject_fields(self): self.page.evaluate("""() => { const request = window.receiptTransport.current; Object.defineProperty(request, 'status', {value: 422}); Object.defineProperty(request, 'response', {value: {errors: { paid_amount: [{message: 'مبلغ با پرداخت مطابقت ندارد.'}], __all__: [{message: 'اطلاعات بانکی را دوباره بررسی کنید.'}] }}}); request.dispatchEvent(new Event('load')); }""") expect(self.page.locator('#receipt-errors')).to_contain_text('اطلاعات بانکی را دوباره بررسی کنید.') expect(self.page.locator('#error-paid_amount')).to_have_text('مبلغ با پرداخت مطابقت ندارد.') expect(self.page.locator('#submit-receipt')).to_be_enabled() def finish(self, revision=False): self.page.evaluate('window.receiptTransport.current.release()') expect(self.page.locator('.flash')).to_contain_text('نسخه اصلاحی ثبت شد' if revision else 'فیش ثبت شد و در انتظار بررسی است.')