Best Python code snippet using playwright-python
documentation_provider.py
Source:documentation_provider.py
...59 continue60 new_name = to_snake_case(new_name)61 member["name"] = new_name62 members[new_name] = member63 apply_type_or_override(member)64 if "args" in member:65 args = {}66 for arg in member["args"]:67 if not works_for_python(arg):68 continue69 if arg["name"] == "options":70 for option in arg["type"]["properties"]:71 if not works_for_python(option):72 continue73 option = self_or_override(option)74 option_name = to_snake_case(name_or_alias(option))75 option["name"] = option_name76 option["required"] = False77 args[option_name] = option78 else:79 arg = self_or_override(arg)80 arg_name = to_snake_case(name_or_alias(arg))81 arg["name"] = arg_name82 args[arg_name] = arg83 member["args"] = args84 clazz["members"] = members85 def _add_link(self, kind: str, clazz: str, member: str, alias: str) -> None:86 match = re.match(r"(JS|CDP|[A-Z])([^.]+)", clazz)87 if not match:88 raise Exception("Invalid class " + clazz)89 var_name = to_snake_case(f"{match.group(1).lower()}{match.group(2)}")90 new_name = to_snake_case(alias)91 if kind == "event":92 self.links[93 f"[`event: {clazz}.{member}`]"94 ] = f"`{var_name}.on('{new_name}')`"95 elif kind == "property":96 self.links[f"[`property: {clazz}.{member}`]"] = f"`{var_name}.{new_name}`"97 else:98 self.links[f"[`method: {clazz}.{member}`]"] = f"`{var_name}.{new_name}()`"99 def print_entry(100 self,101 class_name: str,102 method_name: str,103 signature: Dict[str, Any] = None,104 is_property: bool = False,105 ) -> None:106 if class_name in ["BindingCall"] or method_name in [107 "pid",108 "_add_event_handler",109 "remove_listener",110 ]:111 return112 original_method_name = method_name113 self.printed_entries.append(f"{class_name}.{method_name}")114 clazz = self.classes[class_name]115 method = clazz["members"].get(method_name)116 if not method and "extends" in clazz:117 superclass = self.classes.get(clazz["extends"])118 if superclass:119 method = superclass["members"].get(method_name)120 fqname = f"{class_name}.{method_name}"121 if not method:122 self.errors.add(f"Method not documented: {fqname}")123 return124 doc_is_property = (125 not method.get("async") and not len(method["args"]) and "type" in method126 )127 if method["name"].startswith("is_") or method["name"].startswith("as_"):128 doc_is_property = False129 if doc_is_property != is_property:130 self.errors.add(f"Method vs property mismatch: {fqname}")131 return132 indent = " " * 8133 print(f'{indent}"""{class_name}.{to_snake_case(original_method_name)}')134 if method.get("comment"):135 print(f"{indent}{self.beautify_method_comment(method['comment'], indent)}")136 signature_no_return = {**signature} if signature else None137 if signature_no_return and "return" in signature_no_return:138 del signature_no_return["return"]139 # Collect a list of all names, flatten options.140 args = method["args"]141 if signature and signature_no_return:142 print("")143 print(" Parameters")144 print(" ----------")145 for [name, value] in signature.items():146 name = to_snake_case(name)147 if name == "return":148 continue149 original_name = name150 doc_value = args.get(name)151 if name in args:152 del args[name]153 if not doc_value:154 self.errors.add(f"Parameter not documented: {fqname}({name}=)")155 else:156 code_type = self.serialize_python_type(value)157 print(f"{indent}{to_snake_case(original_name)} : {code_type}")158 if doc_value.get("comment"):159 print(160 f"{indent} {self.indent_paragraph(self.render_links(doc_value['comment']), f'{indent} ')}"161 )162 self.compare_types(code_type, doc_value, f"{fqname}({name}=)", "in")163 if (164 signature165 and "return" in signature166 and str(signature["return"]) != "<class 'NoneType'>"167 ):168 value = signature["return"]169 doc_value = method170 self.compare_types(value, doc_value, f"{fqname}(return=)", "out")171 print("")172 print(" Returns")173 print(" -------")174 print(f" {self.serialize_python_type(value)}")175 print(f'{indent}"""')176 for name in args:177 if args[name].get("deprecated"):178 continue179 self.errors.add(180 f"Parameter not implemented: {class_name}.{method_name}({name}=)"181 )182 def indent_paragraph(self, p: str, indent: str) -> str:183 lines = p.split("\n")184 result = [lines[0]]185 for line in lines[1:]:186 result.append(indent + line)187 return "\n".join(result)188 def beautify_method_comment(self, comment: str, indent: str) -> str:189 comment = comment.replace("\\", "\\\\")190 comment = comment.replace('"', '\\"')191 lines = comment.split("\n")192 result = []193 skip_example = False194 last_was_blank = True195 for line in lines:196 if not line.strip():197 last_was_blank = True198 continue199 match = re.match(r"\s*```(.+)", line)200 if match:201 lang = match[1]202 if lang in ["html", "yml", "sh", "py", "python"]:203 skip_example = False204 elif lang == "python " + ("async" if self.is_async else "sync"):205 skip_example = False206 line = "```py"207 else:208 skip_example = True209 if not skip_example:210 if last_was_blank:211 last_was_blank = False212 result.append("")213 result.append(self.render_links(line))214 if skip_example and line.strip() == "```":215 skip_example = False216 return self.indent_paragraph("\n".join(result), indent)217 def render_links(self, comment: str) -> str:218 for [old, new] in self.links.items():219 comment = comment.replace(old, new)220 return comment221 def make_optional(self, text: str) -> str:222 if text.startswith("Union["):223 if text.endswith("NoneType]"):224 return text225 return text[:-1] + ", NoneType]"226 return f"Union[{text}, NoneType]"227 def compare_types(228 self, value: Any, doc_value: Any, fqname: str, direction: str229 ) -> None:230 if "(arg=)" in fqname or "(pageFunction=)" in fqname:231 return232 code_type = self.serialize_python_type(value)233 doc_type = self.serialize_doc_type(doc_value["type"], direction)234 if not doc_value["required"]:235 doc_type = self.make_optional(doc_type)236 if doc_type != code_type:237 self.errors.add(238 f"Parameter type mismatch in {fqname}: documented as {doc_type}, code has {code_type}"239 )240 def serialize_python_type(self, value: Any) -> str:241 str_value = str(value)242 if isinstance(value, list):243 return f"[{', '.join(list(map(lambda a: self.serialize_python_type(a), value)))}]"244 if str_value == "<class 'playwright._impl._types.Error'>":245 return "Error"246 match = re.match(r"^<class '((?:pathlib\.)?\w+)'>$", str_value)247 if match:248 return match.group(1)249 match = re.match(250 r"playwright._impl._event_context_manager.EventContextManagerImpl\[playwright._impl.[^.]+.(.*)\]",251 str_value,252 )253 if match:254 return "EventContextManager[" + match.group(1) + "]"255 match = re.match(r"^<class 'playwright\._impl\.[\w_]+\.([^']+)'>$", str_value)256 if (257 match258 and "_api_structures" not in str_value259 and "_api_types" not in str_value260 ):261 if match.group(1) == "EventContextManagerImpl":262 return "EventContextManager"263 return match.group(1)264 match = re.match(r"^typing\.(\w+)$", str_value)265 if match:266 return match.group(1)267 origin = get_origin(value)268 args = get_args(value)269 hints = None270 try:271 hints = get_type_hints(value)272 except Exception:273 pass274 if hints:275 signature: List[str] = []276 for [name, value] in hints.items():277 signature.append(f"{name}: {self.serialize_python_type(value)}")278 return f"{{{', '.join(signature)}}}"279 if origin == Union:280 args = get_args(value)281 if len(args) == 2 and str(args[1]) == "<class 'NoneType'>":282 return self.make_optional(self.serialize_python_type(args[0]))283 ll = list(map(lambda a: self.serialize_python_type(a), args))284 ll.sort(key=lambda item: "}" if item == "NoneType" else item)285 return f"Union[{', '.join(ll)}]"286 if str(origin) == "<class 'dict'>":287 args = get_args(value)288 return f"Dict[{', '.join(list(map(lambda a: self.serialize_python_type(a), args)))}]"289 if str(origin) == "<class 'list'>":290 args = get_args(value)291 return f"List[{', '.join(list(map(lambda a: self.serialize_python_type(a), args)))}]"292 if str(origin) == "<class 'collections.abc.Callable'>":293 args = get_args(value)294 return f"Callable[{', '.join(list(map(lambda a: self.serialize_python_type(a), args)))}]"295 if str(origin) == "typing.Literal":296 args = get_args(value)297 if len(args) == 1:298 return '"' + self.serialize_python_type(args[0]) + '"'299 body = ", ".join(300 list(map(lambda a: '"' + self.serialize_python_type(a) + '"', args))301 )302 return f"Union[{body}]"303 return str_value304 def serialize_doc_type(self, type: Any, direction: str) -> str:305 result = self.inner_serialize_doc_type(type, direction)306 return result307 def inner_serialize_doc_type(self, type: Any, direction: str) -> str:308 if type["name"] == "Promise":309 type = type["templates"][0]310 if "union" in type:311 ll = [self.serialize_doc_type(t, direction) for t in type["union"]]312 ll.sort(key=lambda item: "}" if item == "NoneType" else item)313 for i in range(len(ll)):314 if ll[i].startswith("Union["):315 ll[i] = ll[i][6:-1]316 return f"Union[{', '.join(ll)}]"317 type_name = type["name"]318 if type_name == "path":319 if direction == "in":320 return "Union[pathlib.Path, str]"321 else:322 return "pathlib.Path"323 if type_name == "function" and "args" not in type:324 return "Callable"325 if type_name == "function":326 return_type = "Any"327 if type.get("returnType"):328 return_type = self.serialize_doc_type(type["returnType"], direction)329 return f"Callable[[{', '.join(self.serialize_doc_type(t, direction) for t in type['args'])}], {return_type}]"330 if "templates" in type:331 base = type_name332 if type_name == "Array":333 base = "List"334 if type_name == "Object" or type_name == "Map":335 base = "Dict"336 return f"{base}[{', '.join(self.serialize_doc_type(t, direction) for t in type['templates'])}]"337 if type_name == "Object" and "properties" in type:338 items = []339 for p in type["properties"]:340 items.append(341 (p["name"])342 + ": "343 + (344 self.serialize_doc_type(p["type"], direction)345 if p["required"]346 else self.make_optional(347 self.serialize_doc_type(p["type"], direction)348 )349 )350 )351 return f"{{{', '.join(items)}}}"352 if type_name == "boolean":353 return "bool"354 if type_name == "string":355 return "str"356 if type_name == "any" or type_name == "Serializable":357 return "Any"358 if type_name == "Object":359 return "Dict"360 if type_name == "Function":361 return "Callable"362 if type_name == "Buffer":363 return "bytes"364 if type_name == "URL":365 return "str"366 if type_name == "RegExp":367 return "Pattern"368 if type_name == "null":369 return "NoneType"370 if type_name == "EvaluationArgument":371 return "Dict"372 return type["name"]373 def print_remainder(self) -> None:374 for [class_name, clazz] in self.classes.items():375 for [member_name, member] in clazz["members"].items():376 if member.get("deprecated"):377 continue378 entry = f"{class_name}.{member_name}"379 if entry not in self.printed_entries:380 self.errors.add(f"Method not implemented: {entry}")381 with open("scripts/expected_api_mismatch.txt") as f:382 for line in f.readlines():383 sline = line.strip()384 if not len(sline) or sline.startswith("#"):385 continue386 if sline in self.errors:387 self.errors.remove(sline)388 else:389 print("No longer there: " + sline, file=stderr)390 if len(self.errors) > 0:391 for error in self.errors:392 print(error, file=stderr)393 exit(1)394def works_for_python(item: Any) -> bool:395 return not item["langs"].get("only") or "python" in item["langs"]["only"]396def name_or_alias(item: Any) -> str:397 alias = (398 item["langs"].get("aliases").get("python")399 if item["langs"].get("aliases")400 else None401 )402 return alias or item["name"]403def self_or_override(item: Any) -> Any:404 override = (405 item["langs"].get("overrides").get("python")406 if item["langs"].get("overrides")407 else None408 )409 return override or item410def apply_type_or_override(member: Any) -> Any:411 if member["langs"].get("types") and member["langs"]["types"].get("python"):...
LambdaTest’s Playwright tutorial will give you a broader idea about the Playwright automation framework, its unique features, and use cases with examples to exceed your understanding of Playwright testing. This tutorial will give A to Z guidance, from installing the Playwright framework to some best practices and advanced concepts.
Get 100 minutes of automation test minutes FREE!!