diff --git a/playwright/_impl/_impl_to_api_mapping.py b/playwright/_impl/_impl_to_api_mapping.py index e26d22025..8b3cbd756 100644 --- a/playwright/_impl/_impl_to_api_mapping.py +++ b/playwright/_impl/_impl_to_api_mapping.py @@ -119,7 +119,23 @@ def to_impl( def wrap_handler(self, handler: Callable[..., Any]) -> Callable[..., None]: def wrapper_func(*args: Any) -> Any: - arg_count = len(inspect.signature(handler).parameters) + parameters = inspect.signature(handler).parameters + has_varargs = any( + parameter.kind == inspect.Parameter.VAR_POSITIONAL + for parameter in parameters.values() + ) + arg_count = ( + len(args) + if has_varargs + else sum( + parameter.kind + in ( + inspect.Parameter.POSITIONAL_ONLY, + inspect.Parameter.POSITIONAL_OR_KEYWORD, + ) + for parameter in parameters.values() + ) + ) return handler( *list(map(lambda a: self.from_maybe_impl(a), args))[:arg_count] ) diff --git a/tests/common/test_impl_to_api_mapping.py b/tests/common/test_impl_to_api_mapping.py new file mode 100644 index 000000000..74142bc3f --- /dev/null +++ b/tests/common/test_impl_to_api_mapping.py @@ -0,0 +1,29 @@ +# 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. + +from typing import List, Optional + +from playwright._impl._impl_to_api_mapping import ImplToApiMapping + + +def test_wrap_handler_ignores_keyword_only_parameters() -> None: + calls: List[Optional[int]] = [] + + class Input: + def blur(self, *, timeout: Optional[int] = None) -> None: + calls.append(timeout) + + ImplToApiMapping().wrap_handler(Input().blur)("locator") + + assert calls == [None]