Skip to content

Conversation

titusfortner
Copy link
Contributor

Change list

  • Added an asMap method for MobileOptions class to override the one in MutableCapabilities

Types of changes

  • No changes in production code.
  • Bugfix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)

Details

The new MobileOptions classes can force w3c compliance without concerns of backward compatibility since they have not yet been released. Current asMap() implementation is not w3c compliant because it needs to prepend appium:. Essentially I'm looking to be able to merge together Capabilities, the same way Selenium does for browsers

The way I'm reading getW3C() in NewAppiumSessionPayload it should still do the correct thing for all inputs. The only place that seems to get a capability without using the helper is for FORCE_MJSONWP which shouldn't apply to the new options classes, so I don't think it should be a concern.

Note: I can't figure out how to set up my machine for running the entire test suite locally and I can't find any documentation on it, so I can only confirm that the new mobile options classes are working correctly. Any assistance on this would be appreciated.


Map<String, Object> capsMap = super.asMap();
capsMap.forEach((key, value) -> {
if (key.equals("platformName")) {
Copy link
Contributor

Choose a reason for hiding this comment

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

I think it is not only the platform name. W3C defines a bunch of keys, which must be supplied without prefixes and Selenium has this list somewhere in constants

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hmm; platformName is the only one we specify in MobileOptions, but you are probably right here. Looks like NewAppiumSessionPayload uses AcceptedW3CCapabilityKeys which is probably the right fix?

if (key.equals("platformName")) {
toReturn.put(key, value);
} else {
toReturn.put(APPIUM_PREFIX + key, value);
Copy link
Contributor

Choose a reason for hiding this comment

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

should we also check if cap name is already prefixed?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah, I guess if we are allowing people to do setCapability() we should have some protection for that.

Map<String, Object> toReturn = new TreeMap<>();

Map<String, Object> capsMap = super.asMap();
capsMap.forEach((key, value) -> {
Copy link
Contributor

@mykola-mokhnach mykola-mokhnach May 31, 2020

Choose a reason for hiding this comment

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

I think we can build toReturn without having the intermediate capsMap variable, e.g.

return unmodifiableMap(super.asMap().entrySet().stream().map .... collect(Collectors.toMap ...)

I assume toUnmodifiableMap collector has only been added in java10

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I pretty much just copied it from Selenium code, which I think is what happens when you use Selenium 4 with current Appium code? And Selenium browser options I think did more things with the intermediate step, so maybe it can be replaced with your suggestion here, I can try.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

So, I can't figure out how to get the stream to work. This is what I'm working with right now, which removes the redundant capsMap, but still uses toReturn and forEach directly:

        super.asMap().forEach((key, value) -> {
            AcceptedW3CCapabilityKeys acceptedW3CCapabilityKeys = new AcceptedW3CCapabilityKeys();
            if (acceptedW3CCapabilityKeys.test(key) || key.startsWith(APPIUM_PREFIX)) {
                toReturn.put(key, value);
            } else {
                toReturn.put(APPIUM_PREFIX + key, value);
            }
        });

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ok, got a stream figured out. Let me know what you think.

AcceptedW3CCapabilityKeys acceptedW3CCapabilityKeys = new AcceptedW3CCapabilityKeys();

return unmodifiableMap(super.asMap().entrySet().stream().collect(Collectors.toMap(
entry -> (acceptedW3CCapabilityKeys.test(entry.getKey()) || entry.getKey().startsWith(APPIUM_PREFIX)) ?
Copy link
Contributor

Choose a reason for hiding this comment

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

I would move this handler into a separate method for better readability. Also, in Appium server code we don't add prefix if a capability name already contains : character, not just the appium: prefix. Should we consider to do the same here?

@mykola-mokhnach
Copy link
Contributor

Closed in favour of #1540

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants