Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 50 additions & 0 deletions src/main/java/io/appium/java_client/mac/FindsByClassChain.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* See the NOTICE file distributed with this work for additional
* information regarding copyright ownership.
* 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.
*/

package io.appium.java_client.mac;

import io.appium.java_client.FindsByFluentSelector;
import io.appium.java_client.MobileSelector;
import org.openqa.selenium.WebElement;

import java.util.List;

public interface FindsByClassChain<T extends WebElement> extends FindsByFluentSelector<T> {

/**
* Perform single element lookup by class chain expression.
* Read https://github.com/appium/appium-mac2-driver#element-location
* for more details on elements location strategies supported by Mac2 driver.
*
* @param using A valid class chain lookup expression.
* @return The found element
*/
default T findElementByClassChain(String using) {
return findElement(MobileSelector.IOS_CLASS_CHAIN.toString(), using);
}

/**
* Perform multiple elements lookup by class chain search expression.
* Read https://github.com/appium/appium-mac2-driver#element-location
* for more details on elements location strategies supported by Mac2 driver.
*
* @param using A valid class chain lookup expression.
* @return The array of found elements or an empty one if no matches have been found.
*/
default List<T> findElementsByClassChain(String using) {
return findElements(MobileSelector.IOS_CLASS_CHAIN.toString(), using);
}
}
50 changes: 50 additions & 0 deletions src/main/java/io/appium/java_client/mac/FindsByNsPredicate.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* See the NOTICE file distributed with this work for additional
* information regarding copyright ownership.
* 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.
*/

package io.appium.java_client.mac;

import io.appium.java_client.FindsByFluentSelector;
import io.appium.java_client.MobileSelector;
import org.openqa.selenium.WebElement;

import java.util.List;

public interface FindsByNsPredicate<T extends WebElement> extends FindsByFluentSelector<T> {

/**
* Perform single element lookup by predicate search expression.
* Read https://github.com/appium/appium-mac2-driver#element-location
* for more details on elements location strategies supported by Mac2 driver.
*
* @param using A valid predicate lookup expression.
* @return The found element
*/
default T findElementByNsPredicate(String using) {
return findElement(MobileSelector.IOS_PREDICATE_STRING.toString(), using);
}

/**
* Perform multiple elements lookup by predicate search expression.
* Read https://github.com/appium/appium-mac2-driver#element-location
* for more details on elements location strategies supported by Mac2 driver.
*
* @param using A valid predicate lookup expression.
* @return The array of found elements or an empty one if no matches have been found.
*/
default List<T> findElementsByNsPredicate(String using) {
return findElements(MobileSelector.IOS_PREDICATE_STRING.toString(), using);
}
}
101 changes: 101 additions & 0 deletions src/main/java/io/appium/java_client/mac/Mac2Driver.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* See the NOTICE file distributed with this work for additional
* information regarding copyright ownership.
* 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.
*/

package io.appium.java_client.mac;

import io.appium.java_client.AppiumDriver;
import io.appium.java_client.HasSettings;
import io.appium.java_client.internal.CapabilityHelpers;
import io.appium.java_client.remote.AutomationName;
import io.appium.java_client.remote.MobileCapabilityType;
import io.appium.java_client.screenrecording.CanRecordScreen;
import io.appium.java_client.service.local.AppiumDriverLocalService;
import io.appium.java_client.service.local.AppiumServiceBuilder;
import org.openqa.selenium.Capabilities;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.remote.HttpCommandExecutor;
import org.openqa.selenium.remote.http.HttpClient;

import java.net.URL;

import static io.appium.java_client.remote.MobilePlatform.MAC;
import static org.openqa.selenium.remote.CapabilityType.PLATFORM_NAME;

/**
* Mac2Driver is an officially supported Appium driver
* created to automate Mac OS apps. The driver uses W3C
* WebDriver protocol and is built on top of Apple's XCTest
* automation framework. Read https://github.com/appium/appium-mac2-driver
* for more details on how to configure and use it.
*
* @since Appium 1.20.0
*/
public class Mac2Driver<T extends WebElement>
extends AppiumDriver<T> implements CanRecordScreen, FindsByClassChain<T>,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

FindsByNsPredicate<T>, HasSettings {
public Mac2Driver(HttpCommandExecutor executor, Capabilities capabilities) {
super(executor, prepareCaps(capabilities));
}

public Mac2Driver(URL remoteAddress, Capabilities desiredCapabilities) {
super(remoteAddress, prepareCaps(desiredCapabilities));
}

public Mac2Driver(URL remoteAddress, HttpClient.Factory httpClientFactory, Capabilities desiredCapabilities) {
super(remoteAddress, httpClientFactory, prepareCaps(desiredCapabilities));
}

public Mac2Driver(AppiumDriverLocalService service, Capabilities desiredCapabilities) {
super(service, prepareCaps(desiredCapabilities));
}

public Mac2Driver(AppiumDriverLocalService service, HttpClient.Factory httpClientFactory,
Capabilities desiredCapabilities) {
super(service, httpClientFactory, prepareCaps(desiredCapabilities));
}

public Mac2Driver(AppiumServiceBuilder builder, Capabilities desiredCapabilities) {
super(builder, prepareCaps(desiredCapabilities));
}

public Mac2Driver(AppiumServiceBuilder builder, HttpClient.Factory httpClientFactory,
Capabilities desiredCapabilities) {
super(builder, httpClientFactory, prepareCaps(desiredCapabilities));
}

public Mac2Driver(HttpClient.Factory httpClientFactory, Capabilities desiredCapabilities) {
super(httpClientFactory, prepareCaps(desiredCapabilities));
}

public Mac2Driver(Capabilities desiredCapabilities) {
super(prepareCaps(desiredCapabilities));
}

private static Capabilities prepareCaps(Capabilities originalCaps) {
DesiredCapabilities dc = new DesiredCapabilities(originalCaps);
if (originalCaps.getCapability(PLATFORM_NAME) == null) {
dc.setCapability(PLATFORM_NAME, MAC);
}
String automationName = CapabilityHelpers.getCapability(originalCaps,
MobileCapabilityType.AUTOMATION_NAME, String.class);
if (!AutomationName.MAC2.equalsIgnoreCase(automationName)) {
dc.setCapability(CapabilityHelpers.APPIUM_PREFIX
+ MobileCapabilityType.AUTOMATION_NAME, AutomationName.MAC2);
}
return dc;
}
}
23 changes: 23 additions & 0 deletions src/main/java/io/appium/java_client/mac/Mac2Element.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* See the NOTICE file distributed with this work for additional
* information regarding copyright ownership.
* 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.
*/

package io.appium.java_client.mac;

import io.appium.java_client.MobileElement;

public class Mac2Element extends MobileElement implements
FindsByClassChain<MobileElement>, FindsByNsPredicate<MobileElement> {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* See the NOTICE file distributed with this work for additional
* information regarding copyright ownership.
* 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.
*/

package io.appium.java_client.mac;

import com.google.common.collect.ImmutableMap;
import io.appium.java_client.screenrecording.BaseStartScreenRecordingOptions;

import java.time.Duration;
import java.util.Map;

import static java.util.Optional.ofNullable;

public class Mac2StartScreenRecordingOptions
extends BaseStartScreenRecordingOptions<Mac2StartScreenRecordingOptions> {
private Integer fps;
private String videoFilter;
private String preset;
private Boolean captureCursor;
private Boolean captureClicks;
private Integer deviceId;

public static Mac2StartScreenRecordingOptions startScreenRecordingOptions() {
return new Mac2StartScreenRecordingOptions();
}

/**
* The count of frames per second in the resulting video.
* Increasing fps value also increases the size of the resulting
* video file and the CPU usage.
*
* @param fps The actual frames per second value.
* The default value is 15.
* @return self instance for chaining.
*/
public Mac2StartScreenRecordingOptions withFps(int fps) {
this.fps = fps;
return this;
}

/**
* Whether to capture the mouse cursor while recording
* the screen. Disabled by default.
*
* @return self instance for chaining.
*/
public Mac2StartScreenRecordingOptions enableCursorCapture() {
this.captureCursor = true;
return this;
}

/**
* Whether to capture the click gestures while recording
* the screen. Disabled by default.
*
* @return self instance for chaining.
*/
public Mac2StartScreenRecordingOptions enableClicksCapture() {
this.captureClicks = true;
return this;
}

/**
* Screen device index to use for the recording.
* The list of available devices could be retrieved using
* `ffmpeg -f avfoundation -list_devices true -i` command.
* This option is mandatory and must be always provided.
*
* @param deviceId The valid screen device identifier.
* @return self instance for chaining.
*/
public Mac2StartScreenRecordingOptions withDeviceId(Integer deviceId) {
this.deviceId = deviceId;
return this;
}

/**
* The video filter spec to apply for ffmpeg.
* See https://trac.ffmpeg.org/wiki/FilteringGuide for more details on the possible values.
* Example: Set it to `scale=ifnot(gte(iw\,1024)\,iw\,1024):-2` in order to limit the video width
* to 1024px. The height will be adjusted automatically to match the actual screen aspect ratio.
*
* @param videoFilter Valid ffmpeg video filter spec string.
* @return self instance for chaining.
*/
public Mac2StartScreenRecordingOptions withVideoFilter(String videoFilter) {
this.videoFilter = videoFilter;
return this;
}

/**
* A preset is a collection of options that will provide a certain encoding speed to compression ratio.
* A slower preset will provide better compression (compression is quality per filesize).
* This means that, for example, if you target a certain file size or constant bit rate, you will
* achieve better quality with a slower preset. Read https://trac.ffmpeg.org/wiki/Encode/H.264
* for more details.
*
* @param preset One of the supported encoding presets. Possible values are:
* - ultrafast
* - superfast
* - veryfast (default)
* - faster
* - fast
* - medium
* - slow
* - slower
* - veryslow
* @return self instance for chaining.
*/
public Mac2StartScreenRecordingOptions withPreset(String preset) {
this.preset = preset;
return this;
}

/**
* The maximum recording time. The default value is 600 seconds (10 minutes).
* The minimum time resolution unit is one second.
*
* @param timeLimit The actual time limit of the recorded video.
* @return self instance for chaining.
*/
@Override
public Mac2StartScreenRecordingOptions withTimeLimit(Duration timeLimit) {
return super.withTimeLimit(timeLimit);
}

@Override
public Map<String, Object> build() {
final ImmutableMap.Builder<String, Object> builder = ImmutableMap.builder();
builder.putAll(super.build());
ofNullable(fps).map(x -> builder.put("fps", x));
ofNullable(preset).map(x -> builder.put("preset", x));
ofNullable(videoFilter).map(x -> builder.put("videoFilter", x));
ofNullable(captureClicks).map(x -> builder.put("captureClicks", x));
ofNullable(captureCursor).map(x -> builder.put("captureCursor", x));
ofNullable(deviceId).map(x -> builder.put("deviceId", x));
return builder.build();
}
}
Loading