1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79
|
# Copyright (c) Microsoft Corporation.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import re
from typing import Any, List, cast
from playwright.async_api import (
ElementHandle,
Error,
Frame,
Page,
Selectors,
ViewportSize,
)
class Utils:
async def attach_frame(self, page: Page, frame_id: str, url: str) -> Frame:
handle = await page.evaluate_handle(
"""async ({ frame_id, url }) => {
const frame = document.createElement('iframe');
frame.src = url;
frame.id = frame_id;
document.body.appendChild(frame);
await new Promise(x => frame.onload = x);
return frame;
}""",
{"frame_id": frame_id, "url": url},
)
frame = await cast(ElementHandle, handle.as_element()).content_frame()
assert frame
return frame
async def detach_frame(self, page: Page, frame_id: str) -> None:
await page.evaluate(
"frame_id => document.getElementById(frame_id).remove()", frame_id
)
def dump_frames(self, frame: Frame, indentation: str = "") -> List[str]:
indentation = indentation or ""
description = re.sub(r":\d+/", ":<PORT>/", frame.url)
if frame.name:
description += " (" + frame.name + ")"
result = [indentation + description]
sorted_frames = sorted(
frame.child_frames, key=lambda frame: frame.url + frame.name
)
for child in sorted_frames:
result = result + utils.dump_frames(child, " " + indentation)
return result
async def verify_viewport(self, page: Page, width: int, height: int) -> None:
assert cast(ViewportSize, page.viewport_size)["width"] == width
assert cast(ViewportSize, page.viewport_size)["height"] == height
assert await page.evaluate("window.innerWidth") == width
assert await page.evaluate("window.innerHeight") == height
async def register_selector_engine(
self, selectors: Selectors, *args: Any, **kwargs: Any
) -> None:
try:
await selectors.register(*args, **kwargs)
except Error as exc:
if "has been already registered" not in exc.message:
raise exc
utils = Utils()
|