55import os
66from collections .abc import Coroutine
77from typing import Any
8- from urllib .parse import quote
98
109from install_playwright import install
1110from playwright ._impl ._errors import Error as PlaywrightError
@@ -47,8 +46,6 @@ def __init__(
4746 fr_lang : str ,
4847 to_lang : str ,
4948 timeout : int = 15000 ,
50- * ,
51- use_dom_submit : bool = False ,
5249 ) -> None :
5350 """Initialize DeepLCLI.
5451
@@ -76,7 +73,6 @@ def __init__(
7673 self .translated_to_lang : str | None = None
7774 self .max_length = 1500
7875 self .timeout = timeout
79- self .use_dom_submit = use_dom_submit
8076
8177 def translate (self , script : str ) -> str :
8278 """Translate script.
@@ -112,15 +108,14 @@ def translate_async(self, script: str) -> Coroutine[Any, Any, str]:
112108
113109 return self .__translate (script )
114110
115- async def __translate (self , script : str ) -> str : # noqa: PLR0915
111+ async def __translate (self , script : str ) -> str :
116112 """Throw a request."""
117113 async with async_playwright () as p :
118114 browser = await self .__get_browser (p )
119115
120116 page = await browser .new_page ()
121117 page .set_default_timeout (self .timeout )
122-
123- # skip loading page resources for improving performance
118+ await page .set_viewport_size ({"width" : 1920 , "height" : 1080 })
124119 excluded_resources = ["image" , "media" , "font" , "other" ]
125120 await page .route (
126121 "**/*" ,
@@ -130,64 +125,57 @@ async def __translate(self, script: str) -> str: # noqa: PLR0915
130125 )
131126
132127 url = "https://www.deepl.com/en/translator"
133- if self .use_dom_submit :
134- await page .goto (url )
135- else :
136- script = quote (script , safe = "" )
137- await page .goto (f"{ url } #{ self .fr_lang } /{ self .to_lang } /{ script } " )
128+ await page .goto (url )
138129
139- # Wait for loading to complete
140130 try :
141131 page .get_by_role ("main" )
142132 except PlaywrightError as e :
143133 msg = f"Maybe Time limit exceeded. ({ self .timeout } ms)"
144134 raise DeepLCLIPageLoadError (msg ) from e
145135
146- if self .use_dom_submit :
147- with contextlib .suppress (PlaywrightError ):
148- await page .click ("button[data-testid=cookie-banner-strict-accept-all]" )
149- # we also expect the Chrome extension banner to show up
150- with contextlib .suppress (PlaywrightError ):
151- await page .wait_for_function (
152- """
153- () => document.querySelector('div[data-testid="chrome-extension-toast"]')
154- """ ,
155- )
156-
157- # close the extension banner
158- with contextlib .suppress (PlaywrightError ):
159- await page .evaluate (
160- """
161- document.querySelector(
162- 'div[data-testid="chrome-extension-toast"]',
163- ).querySelector('button').click()
164- """ ,
165- )
166-
167- await page .locator (
168- "button[data-testid=translator-source-lang-btn]" ,
169- ).dispatch_event ("click" )
170- await (
171- page .get_by_test_id ("translator-source-lang-list" )
172- .get_by_test_id (
173- f"translator-lang-option-{ self .fr_lang } " ,
174- )
175- .first .dispatch_event ("click" )
136+ with contextlib .suppress (PlaywrightError ):
137+ await page .click ("button[id=cookie-banner-lax-close-button]" )
138+ await page .wait_for_function (
139+ """
140+ () => document.querySelector('div[data-testid="chrome-extension-toast"]')
141+ """ ,
142+ )
143+ await page .evaluate (
144+ """
145+ document.querySelector(
146+ 'div[data-testid="chrome-extension-toast"]',
147+ ).querySelector('button').click()
148+ """ ,
176149 )
177- await page . locator (
178- "button[data-testid=translator-target-lang-btn]" ,
179- ). dispatch_event ( "click" )
180- await (
181- page . get_by_test_id ( "translator-target-lang-list" )
182- . get_by_test_id (
183- f "translator-lang-option- { self . to_lang } " ,
184- )
185- . first . dispatch_event ( "click" )
150+
151+ await page . locator (
152+ "button[data-testid=translator-source-lang-btn]" ,
153+ ). dispatch_event ( "click" )
154+
155+ await (
156+ page . get_by_test_id ( "translator-source- lang-list" )
157+ . get_by_test_id (
158+ f"translator-lang-option- { self . fr_lang } " ,
186159 )
187- await page .fill (
188- "div[aria-labelledby=translation-source-heading]" ,
189- script ,
160+ .first .dispatch_event ("click" )
161+ )
162+
163+ await page .locator (
164+ "button[data-testid=translator-target-lang-btn]" ,
165+ ).dispatch_event ("click" )
166+
167+ await (
168+ page .get_by_test_id ("translator-target-lang-list" )
169+ .get_by_test_id (
170+ f"translator-lang-option-{ self .to_lang } " ,
190171 )
172+ .first .dispatch_event ("click" )
173+ )
174+
175+ await page .fill (
176+ "div[aria-labelledby=translation-source-heading]" ,
177+ script ,
178+ )
191179
192180 try :
193181 await page .wait_for_function (
@@ -201,47 +189,34 @@ async def __translate(self, script: str) -> str: # noqa: PLR0915
201189 msg = f"Time limit exceeded. ({ self .timeout } ms)"
202190 raise DeepLCLIPageLoadError (msg ) from e
203191
192+ # Wait for translation to complete (check that [...] placeholder is gone)
204193 try :
205- line_count = await page .evaluate (
194+ await page .wait_for_function (
206195 """
207- document.querySelector(
208- 'd-textarea[aria-labelledby=translation-target-heading]',
209- ).children[0].children.length
196+ () => {
197+ const elem = document.querySelector('d-textarea[aria-labelledby=translation-target-heading]');
198+ const text = elem?.value ?? '';
199+ return text.length > 0 && !text.includes('[...]');
200+ }
210201 """ ,
202+ timeout = self .timeout ,
211203 )
212204 except PlaywrightError as e :
213- msg = "Unable to evaluate line count of the translation "
205+ msg = f"Translation incomplete after { self . timeout } ms "
214206 raise DeepLCLIPageLoadError (msg ) from e
215207
216- translated_lines = []
217- for line_index in range (line_count ):
218- try :
219- await page .wait_for_function (
220- f"""
221- () => {{
222- t = document.querySelector(
223- 'd-textarea[aria-labelledby=translation-target-heading]',
224- )?.children[0]?.children[{ line_index } ]?.innerText ?? '';
225- return t.length > 0 && !t.includes('[...]');
226- }}
227- """ ,
228- )
229- except PlaywrightError as e :
230- msg = f"Time limit exceeded for line { line_index } . ({ self .timeout } ms)"
231- raise DeepLCLIPageLoadError (msg ) from e
232-
233- try :
234- translated_text = await page .evaluate (
235- f"""
236- document.querySelector(
237- 'd-textarea[aria-labelledby=translation-target-heading]'
238- ).children[0].children[{ line_index } ].innerText
239- """ ,
240- )
241- translated_lines .append (translated_text )
242- except PlaywrightError as e :
243- msg = f"Unable get translated text for line { line_index } "
244- raise DeepLCLIPageLoadError (msg ) from e
208+ # Get the translated text directly from the value attribute
209+ try :
210+ res = await page .evaluate (
211+ """
212+ document.querySelector(
213+ 'd-textarea[aria-labelledby=translation-target-heading]'
214+ ).value
215+ """ ,
216+ )
217+ except PlaywrightError as e :
218+ msg = "Unable to get translated text"
219+ raise DeepLCLIPageLoadError (msg ) from e
245220
246221 input_textbox = page .get_by_role ("region" , name = "Source text" ).locator (
247222 "d-textarea" ,
@@ -258,8 +233,6 @@ async def __translate(self, script: str) -> str: # noqa: PLR0915
258233 await output_textbox .get_attribute ("lang" ),
259234 ).split ("-" )[0 ]
260235
261- res = "\n " .join (translated_lines )
262-
263236 await browser .close ()
264237
265238 return res
0 commit comments