diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 554e34bb..f81bf992 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "0.30.0" + ".": "0.31.0" } \ No newline at end of file diff --git a/.stats.yml b/.stats.yml index 710d8bda..91fd3b68 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ -configured_endpoints: 98 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/kernel%2Fkernel-ccbe854895eb34a9562e33979f5f43cd6ad1f529d5924ee56e56f0c94dcf0454.yml -openapi_spec_hash: 2fa4ecbe742fc46fdde481188c1d885e -config_hash: dd218aae3f852dff79e77febc2077b8e +configured_endpoints: 100 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/kernel%2Fkernel-a6d93dc291278035c96add38bb6150ec2b9ba8bbabb4676e3dbbb8444cf3b1e4.yml +openapi_spec_hash: 694bcc56d94fd0ff0d1f7b0fc1dae8ba +config_hash: 62e33cf2ed8fe0b4ceebba63367481ad diff --git a/CHANGELOG.md b/CHANGELOG.md index 45e5270b..1e7fc045 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,13 @@ # Changelog +## 0.31.0 (2026-02-06) + +Full Changelog: [v0.30.0...v0.31.0](https://github.com/kernel/kernel-python-sdk/compare/v0.30.0...v0.31.0) + +### Features + +* add batch computer action proxy endpoint ([f316e9b](https://github.com/kernel/kernel-python-sdk/commit/f316e9bf1a47e982af7af6ed8a4e8f701baf50b9)) + ## 0.30.0 (2026-02-03) Full Changelog: [v0.29.0...v0.30.0](https://github.com/kernel/kernel-python-sdk/compare/v0.29.0...v0.30.0) diff --git a/api.md b/api.md index 82116657..d55fecff 100644 --- a/api.md +++ b/api.md @@ -187,14 +187,19 @@ Methods: Types: ```python -from kernel.types.browsers import ComputerSetCursorVisibilityResponse +from kernel.types.browsers import ( + ComputerGetMousePositionResponse, + ComputerSetCursorVisibilityResponse, +) ``` Methods: +- client.browsers.computer.batch(id, \*\*params) -> None - client.browsers.computer.capture_screenshot(id, \*\*params) -> BinaryAPIResponse - client.browsers.computer.click_mouse(id, \*\*params) -> None - client.browsers.computer.drag_mouse(id, \*\*params) -> None +- client.browsers.computer.get_mouse_position(id) -> ComputerGetMousePositionResponse - client.browsers.computer.move_mouse(id, \*\*params) -> None - client.browsers.computer.press_key(id, \*\*params) -> None - client.browsers.computer.scroll(id, \*\*params) -> None diff --git a/pyproject.toml b/pyproject.toml index 16affc3d..898d5dfd 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "kernel" -version = "0.30.0" +version = "0.31.0" description = "The official Python library for the kernel API" dynamic = ["readme"] license = "Apache-2.0" diff --git a/src/kernel/_version.py b/src/kernel/_version.py index e08b152b..4d628238 100644 --- a/src/kernel/_version.py +++ b/src/kernel/_version.py @@ -1,4 +1,4 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. __title__ = "kernel" -__version__ = "0.30.0" # x-release-please-version +__version__ = "0.31.0" # x-release-please-version diff --git a/src/kernel/resources/browsers/computer.py b/src/kernel/resources/browsers/computer.py index c23dd3db..933767f0 100644 --- a/src/kernel/resources/browsers/computer.py +++ b/src/kernel/resources/browsers/computer.py @@ -27,6 +27,7 @@ ) from ..._base_client import make_request_options from ...types.browsers import ( + computer_batch_params, computer_scroll_params, computer_press_key_params, computer_type_text_params, @@ -36,6 +37,7 @@ computer_capture_screenshot_params, computer_set_cursor_visibility_params, ) +from ...types.browsers.computer_get_mouse_position_response import ComputerGetMousePositionResponse from ...types.browsers.computer_set_cursor_visibility_response import ComputerSetCursorVisibilityResponse __all__ = ["ComputerResource", "AsyncComputerResource"] @@ -61,6 +63,46 @@ def with_streaming_response(self) -> ComputerResourceWithStreamingResponse: """ return ComputerResourceWithStreamingResponse(self) + def batch( + self, + id: str, + *, + actions: Iterable[computer_batch_params.Action], + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> None: + """ + Send an array of computer actions to execute in order on the browser instance. + Execution stops on the first error. This reduces network latency compared to + sending individual action requests. + + Args: + actions: Ordered list of actions to execute. Execution stops on the first error. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not id: + raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") + extra_headers = {"Accept": "*/*", **(extra_headers or {})} + return self._post( + f"/browsers/{id}/computer/batch", + body=maybe_transform({"actions": actions}, computer_batch_params.ComputerBatchParams), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=NoneType, + ) + def capture_screenshot( self, id: str, @@ -227,6 +269,39 @@ def drag_mouse( cast_to=NoneType, ) + def get_mouse_position( + self, + id: str, + *, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> ComputerGetMousePositionResponse: + """ + Get the current mouse cursor position on the browser instance + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not id: + raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") + return self._post( + f"/browsers/{id}/computer/get_mouse_position", + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=ComputerGetMousePositionResponse, + ) + def move_mouse( self, id: str, @@ -499,6 +574,46 @@ def with_streaming_response(self) -> AsyncComputerResourceWithStreamingResponse: """ return AsyncComputerResourceWithStreamingResponse(self) + async def batch( + self, + id: str, + *, + actions: Iterable[computer_batch_params.Action], + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> None: + """ + Send an array of computer actions to execute in order on the browser instance. + Execution stops on the first error. This reduces network latency compared to + sending individual action requests. + + Args: + actions: Ordered list of actions to execute. Execution stops on the first error. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not id: + raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") + extra_headers = {"Accept": "*/*", **(extra_headers or {})} + return await self._post( + f"/browsers/{id}/computer/batch", + body=await async_maybe_transform({"actions": actions}, computer_batch_params.ComputerBatchParams), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=NoneType, + ) + async def capture_screenshot( self, id: str, @@ -665,6 +780,39 @@ async def drag_mouse( cast_to=NoneType, ) + async def get_mouse_position( + self, + id: str, + *, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> ComputerGetMousePositionResponse: + """ + Get the current mouse cursor position on the browser instance + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not id: + raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") + return await self._post( + f"/browsers/{id}/computer/get_mouse_position", + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=ComputerGetMousePositionResponse, + ) + async def move_mouse( self, id: str, @@ -921,6 +1069,9 @@ class ComputerResourceWithRawResponse: def __init__(self, computer: ComputerResource) -> None: self._computer = computer + self.batch = to_raw_response_wrapper( + computer.batch, + ) self.capture_screenshot = to_custom_raw_response_wrapper( computer.capture_screenshot, BinaryAPIResponse, @@ -931,6 +1082,9 @@ def __init__(self, computer: ComputerResource) -> None: self.drag_mouse = to_raw_response_wrapper( computer.drag_mouse, ) + self.get_mouse_position = to_raw_response_wrapper( + computer.get_mouse_position, + ) self.move_mouse = to_raw_response_wrapper( computer.move_mouse, ) @@ -952,6 +1106,9 @@ class AsyncComputerResourceWithRawResponse: def __init__(self, computer: AsyncComputerResource) -> None: self._computer = computer + self.batch = async_to_raw_response_wrapper( + computer.batch, + ) self.capture_screenshot = async_to_custom_raw_response_wrapper( computer.capture_screenshot, AsyncBinaryAPIResponse, @@ -962,6 +1119,9 @@ def __init__(self, computer: AsyncComputerResource) -> None: self.drag_mouse = async_to_raw_response_wrapper( computer.drag_mouse, ) + self.get_mouse_position = async_to_raw_response_wrapper( + computer.get_mouse_position, + ) self.move_mouse = async_to_raw_response_wrapper( computer.move_mouse, ) @@ -983,6 +1143,9 @@ class ComputerResourceWithStreamingResponse: def __init__(self, computer: ComputerResource) -> None: self._computer = computer + self.batch = to_streamed_response_wrapper( + computer.batch, + ) self.capture_screenshot = to_custom_streamed_response_wrapper( computer.capture_screenshot, StreamedBinaryAPIResponse, @@ -993,6 +1156,9 @@ def __init__(self, computer: ComputerResource) -> None: self.drag_mouse = to_streamed_response_wrapper( computer.drag_mouse, ) + self.get_mouse_position = to_streamed_response_wrapper( + computer.get_mouse_position, + ) self.move_mouse = to_streamed_response_wrapper( computer.move_mouse, ) @@ -1014,6 +1180,9 @@ class AsyncComputerResourceWithStreamingResponse: def __init__(self, computer: AsyncComputerResource) -> None: self._computer = computer + self.batch = async_to_streamed_response_wrapper( + computer.batch, + ) self.capture_screenshot = async_to_custom_streamed_response_wrapper( computer.capture_screenshot, AsyncStreamedBinaryAPIResponse, @@ -1024,6 +1193,9 @@ def __init__(self, computer: AsyncComputerResource) -> None: self.drag_mouse = async_to_streamed_response_wrapper( computer.drag_mouse, ) + self.get_mouse_position = async_to_streamed_response_wrapper( + computer.get_mouse_position, + ) self.move_mouse = async_to_streamed_response_wrapper( computer.move_mouse, ) diff --git a/src/kernel/types/browsers/__init__.py b/src/kernel/types/browsers/__init__.py index e6b2eca3..3daee051 100644 --- a/src/kernel/types/browsers/__init__.py +++ b/src/kernel/types/browsers/__init__.py @@ -18,6 +18,7 @@ from .process_spawn_params import ProcessSpawnParams as ProcessSpawnParams from .process_stdin_params import ProcessStdinParams as ProcessStdinParams from .replay_list_response import ReplayListResponse as ReplayListResponse +from .computer_batch_params import ComputerBatchParams as ComputerBatchParams from .f_list_files_response import FListFilesResponse as FListFilesResponse from .process_exec_response import ProcessExecResponse as ProcessExecResponse from .process_kill_response import ProcessKillResponse as ProcessKillResponse @@ -41,6 +42,7 @@ from .f_set_file_permissions_params import FSetFilePermissionsParams as FSetFilePermissionsParams from .process_stdout_stream_response import ProcessStdoutStreamResponse as ProcessStdoutStreamResponse from .computer_capture_screenshot_params import ComputerCaptureScreenshotParams as ComputerCaptureScreenshotParams +from .computer_get_mouse_position_response import ComputerGetMousePositionResponse as ComputerGetMousePositionResponse from .computer_set_cursor_visibility_params import ( ComputerSetCursorVisibilityParams as ComputerSetCursorVisibilityParams, ) diff --git a/src/kernel/types/browsers/computer_batch_params.py b/src/kernel/types/browsers/computer_batch_params.py new file mode 100644 index 00000000..601cd2b9 --- /dev/null +++ b/src/kernel/types/browsers/computer_batch_params.py @@ -0,0 +1,170 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Iterable +from typing_extensions import Literal, Required, TypedDict + +from ..._types import SequenceNotStr + +__all__ = [ + "ComputerBatchParams", + "Action", + "ActionClickMouse", + "ActionDragMouse", + "ActionMoveMouse", + "ActionPressKey", + "ActionScroll", + "ActionSetCursor", + "ActionSleep", + "ActionTypeText", +] + + +class ComputerBatchParams(TypedDict, total=False): + actions: Required[Iterable[Action]] + """Ordered list of actions to execute. Execution stops on the first error.""" + + +class ActionClickMouse(TypedDict, total=False): + x: Required[int] + """X coordinate of the click position""" + + y: Required[int] + """Y coordinate of the click position""" + + button: Literal["left", "right", "middle", "back", "forward"] + """Mouse button to interact with""" + + click_type: Literal["down", "up", "click"] + """Type of click action""" + + hold_keys: SequenceNotStr[str] + """Modifier keys to hold during the click""" + + num_clicks: int + """Number of times to repeat the click""" + + +class ActionDragMouse(TypedDict, total=False): + path: Required[Iterable[Iterable[int]]] + """Ordered list of [x, y] coordinate pairs to move through while dragging. + + Must contain at least 2 points. + """ + + button: Literal["left", "middle", "right"] + """Mouse button to drag with""" + + delay: int + """Delay in milliseconds between button down and starting to move along the path.""" + + hold_keys: SequenceNotStr[str] + """Modifier keys to hold during the drag""" + + step_delay_ms: int + """ + Delay in milliseconds between relative steps while dragging (not the initial + delay). + """ + + steps_per_segment: int + """Number of relative move steps per segment in the path. Minimum 1.""" + + +class ActionMoveMouse(TypedDict, total=False): + x: Required[int] + """X coordinate to move the cursor to""" + + y: Required[int] + """Y coordinate to move the cursor to""" + + hold_keys: SequenceNotStr[str] + """Modifier keys to hold during the move""" + + +class ActionPressKey(TypedDict, total=False): + keys: Required[SequenceNotStr[str]] + """List of key symbols to press. + + Each item should be a key symbol supported by xdotool (see X11 keysym + definitions). Examples include "Return", "Shift", "Ctrl", "Alt", "F5". Items in + this list could also be combinations, e.g. "Ctrl+t" or "Ctrl+Shift+Tab". + """ + + duration: int + """Duration to hold the keys down in milliseconds. + + If omitted or 0, keys are tapped. + """ + + hold_keys: SequenceNotStr[str] + """Optional modifier keys to hold during the key press sequence.""" + + +class ActionScroll(TypedDict, total=False): + x: Required[int] + """X coordinate at which to perform the scroll""" + + y: Required[int] + """Y coordinate at which to perform the scroll""" + + delta_x: int + """Horizontal scroll amount. Positive scrolls right, negative scrolls left.""" + + delta_y: int + """Vertical scroll amount. Positive scrolls down, negative scrolls up.""" + + hold_keys: SequenceNotStr[str] + """Modifier keys to hold during the scroll""" + + +class ActionSetCursor(TypedDict, total=False): + hidden: Required[bool] + """Whether the cursor should be hidden or visible""" + + +class ActionSleep(TypedDict, total=False): + """Pause execution for a specified duration.""" + + duration_ms: Required[int] + """Duration to sleep in milliseconds.""" + + +class ActionTypeText(TypedDict, total=False): + text: Required[str] + """Text to type on the browser instance""" + + delay: int + """Delay in milliseconds between keystrokes""" + + +class Action(TypedDict, total=False): + """A single computer action to execute as part of a batch. + + The `type` field selects which + action to perform, and the corresponding field contains the action parameters. + Exactly one action field matching the type must be provided. + """ + + type: Required[ + Literal["click_mouse", "move_mouse", "type_text", "press_key", "scroll", "drag_mouse", "set_cursor", "sleep"] + ] + """The type of action to perform.""" + + click_mouse: ActionClickMouse + + drag_mouse: ActionDragMouse + + move_mouse: ActionMoveMouse + + press_key: ActionPressKey + + scroll: ActionScroll + + set_cursor: ActionSetCursor + + sleep: ActionSleep + """Pause execution for a specified duration.""" + + type_text: ActionTypeText diff --git a/src/kernel/types/browsers/computer_get_mouse_position_response.py b/src/kernel/types/browsers/computer_get_mouse_position_response.py new file mode 100644 index 00000000..53cdc4ad --- /dev/null +++ b/src/kernel/types/browsers/computer_get_mouse_position_response.py @@ -0,0 +1,13 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from ..._models import BaseModel + +__all__ = ["ComputerGetMousePositionResponse"] + + +class ComputerGetMousePositionResponse(BaseModel): + x: int + """X coordinate of the cursor""" + + y: int + """Y coordinate of the cursor""" diff --git a/tests/api_resources/browsers/test_computer.py b/tests/api_resources/browsers/test_computer.py index 7634b89b..f98f81af 100644 --- a/tests/api_resources/browsers/test_computer.py +++ b/tests/api_resources/browsers/test_computer.py @@ -18,6 +18,7 @@ AsyncStreamedBinaryAPIResponse, ) from kernel.types.browsers import ( + ComputerGetMousePositionResponse, ComputerSetCursorVisibilityResponse, ) @@ -27,6 +28,52 @@ class TestComputer: parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) + @pytest.mark.skip(reason="Prism tests are disabled") + @parametrize + def test_method_batch(self, client: Kernel) -> None: + computer = client.browsers.computer.batch( + id="id", + actions=[{"type": "click_mouse"}], + ) + assert computer is None + + @pytest.mark.skip(reason="Prism tests are disabled") + @parametrize + def test_raw_response_batch(self, client: Kernel) -> None: + response = client.browsers.computer.with_raw_response.batch( + id="id", + actions=[{"type": "click_mouse"}], + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + computer = response.parse() + assert computer is None + + @pytest.mark.skip(reason="Prism tests are disabled") + @parametrize + def test_streaming_response_batch(self, client: Kernel) -> None: + with client.browsers.computer.with_streaming_response.batch( + id="id", + actions=[{"type": "click_mouse"}], + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + computer = response.parse() + assert computer is None + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Prism tests are disabled") + @parametrize + def test_path_params_batch(self, client: Kernel) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"): + client.browsers.computer.with_raw_response.batch( + id="", + actions=[{"type": "click_mouse"}], + ) + @parametrize @pytest.mark.respx(base_url=base_url) def test_method_capture_screenshot(self, client: Kernel, respx_mock: MockRouter) -> None: @@ -219,6 +266,48 @@ def test_path_params_drag_mouse(self, client: Kernel) -> None: path=[[0, 0], [0, 0]], ) + @pytest.mark.skip(reason="Prism tests are disabled") + @parametrize + def test_method_get_mouse_position(self, client: Kernel) -> None: + computer = client.browsers.computer.get_mouse_position( + "id", + ) + assert_matches_type(ComputerGetMousePositionResponse, computer, path=["response"]) + + @pytest.mark.skip(reason="Prism tests are disabled") + @parametrize + def test_raw_response_get_mouse_position(self, client: Kernel) -> None: + response = client.browsers.computer.with_raw_response.get_mouse_position( + "id", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + computer = response.parse() + assert_matches_type(ComputerGetMousePositionResponse, computer, path=["response"]) + + @pytest.mark.skip(reason="Prism tests are disabled") + @parametrize + def test_streaming_response_get_mouse_position(self, client: Kernel) -> None: + with client.browsers.computer.with_streaming_response.get_mouse_position( + "id", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + computer = response.parse() + assert_matches_type(ComputerGetMousePositionResponse, computer, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Prism tests are disabled") + @parametrize + def test_path_params_get_mouse_position(self, client: Kernel) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"): + client.browsers.computer.with_raw_response.get_mouse_position( + "", + ) + @pytest.mark.skip(reason="Prism tests are disabled") @parametrize def test_method_move_mouse(self, client: Kernel) -> None: @@ -508,6 +597,52 @@ class TestAsyncComputer: "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] ) + @pytest.mark.skip(reason="Prism tests are disabled") + @parametrize + async def test_method_batch(self, async_client: AsyncKernel) -> None: + computer = await async_client.browsers.computer.batch( + id="id", + actions=[{"type": "click_mouse"}], + ) + assert computer is None + + @pytest.mark.skip(reason="Prism tests are disabled") + @parametrize + async def test_raw_response_batch(self, async_client: AsyncKernel) -> None: + response = await async_client.browsers.computer.with_raw_response.batch( + id="id", + actions=[{"type": "click_mouse"}], + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + computer = await response.parse() + assert computer is None + + @pytest.mark.skip(reason="Prism tests are disabled") + @parametrize + async def test_streaming_response_batch(self, async_client: AsyncKernel) -> None: + async with async_client.browsers.computer.with_streaming_response.batch( + id="id", + actions=[{"type": "click_mouse"}], + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + computer = await response.parse() + assert computer is None + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Prism tests are disabled") + @parametrize + async def test_path_params_batch(self, async_client: AsyncKernel) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"): + await async_client.browsers.computer.with_raw_response.batch( + id="", + actions=[{"type": "click_mouse"}], + ) + @parametrize @pytest.mark.respx(base_url=base_url) async def test_method_capture_screenshot(self, async_client: AsyncKernel, respx_mock: MockRouter) -> None: @@ -704,6 +839,48 @@ async def test_path_params_drag_mouse(self, async_client: AsyncKernel) -> None: path=[[0, 0], [0, 0]], ) + @pytest.mark.skip(reason="Prism tests are disabled") + @parametrize + async def test_method_get_mouse_position(self, async_client: AsyncKernel) -> None: + computer = await async_client.browsers.computer.get_mouse_position( + "id", + ) + assert_matches_type(ComputerGetMousePositionResponse, computer, path=["response"]) + + @pytest.mark.skip(reason="Prism tests are disabled") + @parametrize + async def test_raw_response_get_mouse_position(self, async_client: AsyncKernel) -> None: + response = await async_client.browsers.computer.with_raw_response.get_mouse_position( + "id", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + computer = await response.parse() + assert_matches_type(ComputerGetMousePositionResponse, computer, path=["response"]) + + @pytest.mark.skip(reason="Prism tests are disabled") + @parametrize + async def test_streaming_response_get_mouse_position(self, async_client: AsyncKernel) -> None: + async with async_client.browsers.computer.with_streaming_response.get_mouse_position( + "id", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + computer = await response.parse() + assert_matches_type(ComputerGetMousePositionResponse, computer, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Prism tests are disabled") + @parametrize + async def test_path_params_get_mouse_position(self, async_client: AsyncKernel) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"): + await async_client.browsers.computer.with_raw_response.get_mouse_position( + "", + ) + @pytest.mark.skip(reason="Prism tests are disabled") @parametrize async def test_method_move_mouse(self, async_client: AsyncKernel) -> None: