diff --git a/Winium/TestApp.Test/py-functional/tests/__init__.py b/Winium/TestApp.Test/py-functional/tests/__init__.py index 5a2e6dc..3b07ff9 100644 --- a/Winium/TestApp.Test/py-functional/tests/__init__.py +++ b/Winium/TestApp.Test/py-functional/tests/__init__.py @@ -1,6 +1,6 @@ # coding: utf-8 import pytest -from selenium.webdriver import Remote +from appium.webdriver import Remote from selenium.webdriver.support.wait import WebDriverWait import config diff --git a/Winium/TestApp.Test/py-functional/tests/test_commands.py b/Winium/TestApp.Test/py-functional/tests/test_commands.py index 45b838e..66c137a 100644 --- a/Winium/TestApp.Test/py-functional/tests/test_commands.py +++ b/Winium/TestApp.Test/py-functional/tests/test_commands.py @@ -1,5 +1,6 @@ # coding: utf-8 from time import sleep +import base64 import pytest from selenium.common.exceptions import NoSuchElementException, NoAlertPresentException, WebDriverException @@ -171,6 +172,13 @@ def test_is_displayed(self): assert self.driver.find_element_by_name('June').is_displayed() assert not self.driver.find_element_by_name('August').is_displayed() + def test_file_ops(self): + with open(__file__) as f: + encoded = base64.b64encode(f.read()) + self.driver.push_file(r"test\sample.dat", encoded) + data = self.driver.pull_file(r"test\sample.dat") + assert encoded == data + class UsesSecondTab(WuaTestCase): @pytest.fixture diff --git a/Winium/Winium.Mobile.Connectivity/Deployer.cs b/Winium/Winium.Mobile.Connectivity/Deployer.cs index 906a91f..76dcc9d 100644 --- a/Winium/Winium.Mobile.Connectivity/Deployer.cs +++ b/Winium/Winium.Mobile.Connectivity/Deployer.cs @@ -109,8 +109,14 @@ public void Launch() public void ReceiveFile(string isoStoreRoot, string sourceDeviceFilePath, string targetDesktopFilePath) { - this.RemoteApplication.GetIsolatedStore(isoStoreRoot) - .ReceiveFile(sourceDeviceFilePath, targetDesktopFilePath, true); + var isolatedStore = this.RemoteApplication.GetIsolatedStore(isoStoreRoot); + isolatedStore.ReceiveFile(sourceDeviceFilePath, targetDesktopFilePath, true); + } + + public void SendFile(string isoStoreRoot, string sourceDesktopFilePath, string targetDeviceFilePath) + { + var isolatedStore = this.RemoteApplication.GetIsolatedStore(isoStoreRoot); + isolatedStore.SendFile(sourceDesktopFilePath, targetDeviceFilePath, true); } public void SendFiles(List> files) diff --git a/Winium/Winium.Mobile.Connectivity/IDeployer.cs b/Winium/Winium.Mobile.Connectivity/IDeployer.cs index cc593e3..791cc21 100644 --- a/Winium/Winium.Mobile.Connectivity/IDeployer.cs +++ b/Winium/Winium.Mobile.Connectivity/IDeployer.cs @@ -26,6 +26,8 @@ public interface IDeployer void SendFiles(List> files); + void SendFile(string isoStoreRoot, string sourceDesktopFilePath, string targetDeviceFilePath); + void Terminate(); void Uninstall(); diff --git a/Winium/Winium.StoreApps.Common/DriverCommand.cs b/Winium/Winium.StoreApps.Common/DriverCommand.cs index 1748cb9..ca9bc50 100644 --- a/Winium/Winium.StoreApps.Common/DriverCommand.cs +++ b/Winium/Winium.StoreApps.Common/DriverCommand.cs @@ -481,6 +481,10 @@ public static class DriverCommand public static readonly string CloseApp = "closeApp"; + public static readonly string PullFile = "pullFile"; + + public static readonly string PushFile = "pushFile"; + #endregion #endregion diff --git a/Winium/Winium.StoreApps.Driver/CommandExecutors/PullFileExecutor.cs b/Winium/Winium.StoreApps.Driver/CommandExecutors/PullFileExecutor.cs new file mode 100644 index 0000000..5c44777 --- /dev/null +++ b/Winium/Winium.StoreApps.Driver/CommandExecutors/PullFileExecutor.cs @@ -0,0 +1,35 @@ +namespace Winium.StoreApps.Driver.CommandExecutors +{ + using System; + using System.IO; + + using Winium.StoreApps.Common; + using Winium.StoreApps.Driver.Automator; + + internal class PullFileExecutor : CommandExecutorBase + { + #region Methods + + protected override string DoImpl() + { + var path = Automator.GetValue(this.ExecutedCommand.Parameters, "path"); + + var localPath = Path.GetTempFileName(); + + try + { + this.Automator.Deployer.ReceiveFile("Local", path, localPath); + + var bytes = File.ReadAllBytes(localPath); + var data = Convert.ToBase64String(bytes); + return this.JsonResponse(ResponseStatus.Success, data); + } + finally + { + File.Delete(localPath); + } + } + + #endregion + } +} \ No newline at end of file diff --git a/Winium/Winium.StoreApps.Driver/CommandExecutors/PushFileExecutor.cs b/Winium/Winium.StoreApps.Driver/CommandExecutors/PushFileExecutor.cs new file mode 100644 index 0000000..06e17d0 --- /dev/null +++ b/Winium/Winium.StoreApps.Driver/CommandExecutors/PushFileExecutor.cs @@ -0,0 +1,34 @@ +namespace Winium.StoreApps.Driver.CommandExecutors +{ + using System; + using System.IO; + + using Winium.StoreApps.Driver.Automator; + + internal class PushFileExecutor : CommandExecutorBase + { + #region Methods + + protected override string DoImpl() + { + var path = Automator.GetValue(this.ExecutedCommand.Parameters, "path"); + var data = Automator.GetValue(this.ExecutedCommand.Parameters, "data"); + + var localPath = Path.GetTempFileName(); + + try + { + File.WriteAllBytes(localPath, Convert.FromBase64String(data)); + this.Automator.Deployer.SendFile("Local", localPath, path); + } + finally + { + File.Delete(localPath); + } + + return this.JsonResponse(); + } + + #endregion + } +} \ No newline at end of file diff --git a/Winium/Winium.StoreApps.Driver/UriDispatchTables.cs b/Winium/Winium.StoreApps.Driver/UriDispatchTables.cs index 4b81aef..4886415 100644 --- a/Winium/Winium.StoreApps.Driver/UriDispatchTables.cs +++ b/Winium/Winium.StoreApps.Driver/UriDispatchTables.cs @@ -292,13 +292,25 @@ private void InitializeSeleniumCommandDictionary() private void InitializeWiniumCommandDictionary() { - this.commandDictionary.Add(DriverCommand.GetElementRect, new CommandInfo("GET", "/session/{sessionId}/element/{id}/rect")); + this.commandDictionary.Add( + DriverCommand.GetElementRect, + new CommandInfo("GET", "/session/{sessionId}/element/{id}/rect")); } private void InitializeAppiumCommandDictionary() { - this.commandDictionary.Add(DriverCommand.LaunchApp, new CommandInfo("POST", "/session/{sessionId}/appium/app/launch")); - this.commandDictionary.Add(DriverCommand.CloseApp, new CommandInfo("POST", "/session/{sessionId}/appium/app/close")); + this.commandDictionary.Add( + DriverCommand.LaunchApp, + new CommandInfo("POST", "/session/{sessionId}/appium/app/launch")); + this.commandDictionary.Add( + DriverCommand.CloseApp, + new CommandInfo("POST", "/session/{sessionId}/appium/app/close")); + this.commandDictionary.Add( + DriverCommand.PullFile, + new CommandInfo("POST", "/session/{sessionId}/appium/device/pull_file")); + this.commandDictionary.Add( + DriverCommand.PushFile, + new CommandInfo("POST", "/session/{sessionId}/appium/device/push_file")); } #endregion diff --git a/Winium/Winium.StoreApps.Driver/Winium.StoreApps.Driver.csproj b/Winium/Winium.StoreApps.Driver/Winium.StoreApps.Driver.csproj index d847afa..4f96239 100644 --- a/Winium/Winium.StoreApps.Driver/Winium.StoreApps.Driver.csproj +++ b/Winium/Winium.StoreApps.Driver/Winium.StoreApps.Driver.csproj @@ -59,6 +59,8 @@ + + diff --git a/Winium/Winium.sln.DotSettings b/Winium/Winium.sln.DotSettings index 4a11c4f..767c2ba 100644 --- a/Winium/Winium.sln.DotSettings +++ b/Winium/Winium.sln.DotSettings @@ -15,9 +15,9 @@ DO_NOT_SHOW DO_NOT_SHOW <?xml version="1.0" encoding="utf-16"?><Profile name="AutoQACleanupCode"><StyleCop.Ordering><AlphabeticalUsingDirectives>Ignore</AlphabeticalUsingDirectives><ExpandUsingDirectives>FullyQualify</ExpandUsingDirectives><SA1212PropertyAccessorsMustFollowOrder>True</SA1212PropertyAccessorsMustFollowOrder><SA1213EventAccessorsMustFollowOrder>True</SA1213EventAccessorsMustFollowOrder></StyleCop.Ordering><StyleCop.Documentation><SA1600ElementsMustBeDocumented>False</SA1600ElementsMustBeDocumented><SA1604ElementDocumentationMustHaveSummary>False</SA1604ElementDocumentationMustHaveSummary><SA1609PropertyDocumentationMustHaveValueDocumented>False</SA1609PropertyDocumentationMustHaveValueDocumented><SA1611ElementParametersMustBeDocumented>False</SA1611ElementParametersMustBeDocumented><SA1615ElementReturnValueMustBeDocumented>False</SA1615ElementReturnValueMustBeDocumented><SA1617VoidReturnValueMustNotBeDocumented>False</SA1617VoidReturnValueMustNotBeDocumented><SA1618GenericTypeParametersMustBeDocumented>False</SA1618GenericTypeParametersMustBeDocumented><SA1626SingleLineCommentsMustNotUseDocumentationStyleSlashes>False</SA1626SingleLineCommentsMustNotUseDocumentationStyleSlashes><SA1628DocumentationTextMustBeginWithACapitalLetter>False</SA1628DocumentationTextMustBeginWithACapitalLetter><SA1629DocumentationTextMustEndWithAPeriod>False</SA1629DocumentationTextMustEndWithAPeriod><SA1633SA1641UpdateFileHeader>Ignore</SA1633SA1641UpdateFileHeader><SA1639FileHeaderMustHaveSummary>False</SA1639FileHeaderMustHaveSummary><SA1642ConstructorSummaryDocumentationMustBeginWithStandardText>False</SA1642ConstructorSummaryDocumentationMustBeginWithStandardText><SA1643DestructorSummaryDocumentationMustBeginWithStandardText>False</SA1643DestructorSummaryDocumentationMustBeginWithStandardText><SA1644DocumentationHeadersMustNotContainBlankLines>False</SA1644DocumentationHeadersMustNotContainBlankLines></StyleCop.Documentation><CSArrangeThisQualifier>True</CSArrangeThisQualifier><RemoveCodeRedundancies>True</RemoveCodeRedundancies><CSUseAutoProperty>True</CSUseAutoProperty><CSMakeFieldReadonly>True</CSMakeFieldReadonly><CSUseVar><BehavourStyle>CAN_CHANGE_TO_IMPLICIT</BehavourStyle><LocalVariableStyle>IMPLICIT_WHEN_INITIALIZER_HAS_TYPE</LocalVariableStyle><ForeachVariableStyle>ALWAYS_EXPLICIT</ForeachVariableStyle></CSUseVar><CSOptimizeUsings><OptimizeUsings>True</OptimizeUsings><EmbraceInRegion>True</EmbraceInRegion><RegionName>using</RegionName></CSOptimizeUsings><CSReformatCode>True</CSReformatCode><CSReorderTypeMembers>True</CSReorderTypeMembers><CSShortenReferences>True</CSShortenReferences></Profile> - <?xml version="1.0" encoding="utf-16"?><Profile name="StyleCop"><CSArrangeThisQualifier>True</CSArrangeThisQualifier><CSOptimizeUsings><OptimizeUsings>True</OptimizeUsings><EmbraceInRegion>True</EmbraceInRegion><RegionName></RegionName></CSOptimizeUsings><CSReformatCode>True</CSReformatCode><CSReorderTypeMembers>True</CSReorderTypeMembers><StyleCop.Documentation><SA1600ElementsMustBeDocumented>False</SA1600ElementsMustBeDocumented><SA1604ElementDocumentationMustHaveSummary>True</SA1604ElementDocumentationMustHaveSummary><SA1609PropertyDocumentationMustHaveValueDocumented>True</SA1609PropertyDocumentationMustHaveValueDocumented><SA1611ElementParametersMustBeDocumented>True</SA1611ElementParametersMustBeDocumented><SA1615ElementReturnValueMustBeDocumented>True</SA1615ElementReturnValueMustBeDocumented><SA1617VoidReturnValueMustNotBeDocumented>True</SA1617VoidReturnValueMustNotBeDocumented><SA1618GenericTypeParametersMustBeDocumented>True</SA1618GenericTypeParametersMustBeDocumented><SA1626SingleLineCommentsMustNotUseDocumentationStyleSlashes>True</SA1626SingleLineCommentsMustNotUseDocumentationStyleSlashes><SA1628DocumentationTextMustBeginWithACapitalLetter>True</SA1628DocumentationTextMustBeginWithACapitalLetter><SA1629DocumentationTextMustEndWithAPeriod>True</SA1629DocumentationTextMustEndWithAPeriod><SA1633SA1641UpdateFileHeader>Ignore</SA1633SA1641UpdateFileHeader><SA1639FileHeaderMustHaveSummary>True</SA1639FileHeaderMustHaveSummary><SA1642ConstructorSummaryDocumentationMustBeginWithStandardText>True</SA1642ConstructorSummaryDocumentationMustBeginWithStandardText><SA1643DestructorSummaryDocumentationMustBeginWithStandardText>True</SA1643DestructorSummaryDocumentationMustBeginWithStandardText><SA1644DocumentationHeadersMustNotContainBlankLines>True</SA1644DocumentationHeadersMustNotContainBlankLines></StyleCop.Documentation><StyleCop.Layout><SA1500CurlyBracketsForMultiLineStatementsMustNotShareLine>True</SA1500CurlyBracketsForMultiLineStatementsMustNotShareLine><SA1509OpeningCurlyBracketsMustNotBePrecededByBlankLine>True</SA1509OpeningCurlyBracketsMustNotBePrecededByBlankLine><SA1510ChainedStatementBlocksMustNotBePrecededByBlankLine>True</SA1510ChainedStatementBlocksMustNotBePrecededByBlankLine><SA1511WhileDoFooterMustNotBePrecededByBlankLine>True</SA1511WhileDoFooterMustNotBePrecededByBlankLine><SA1512SingleLineCommentsMustNotBeFollowedByBlankLine>True</SA1512SingleLineCommentsMustNotBeFollowedByBlankLine><SA1513ClosingCurlyBracketMustBeFollowedByBlankLine>True</SA1513ClosingCurlyBracketMustBeFollowedByBlankLine><SA1514ElementDocumentationHeaderMustBePrecededByBlankLine>True</SA1514ElementDocumentationHeaderMustBePrecededByBlankLine><SA1515SingleLineCommentMustBeProceededByBlankLine>True</SA1515SingleLineCommentMustBeProceededByBlankLine></StyleCop.Layout><StyleCop.Maintainability><SA1119StatementMustNotUseUnnecessaryParenthesis>True</SA1119StatementMustNotUseUnnecessaryParenthesis></StyleCop.Maintainability><StyleCop.Ordering><AlphabeticalUsingDirectives>Alphabetical</AlphabeticalUsingDirectives><ExpandUsingDirectives>FullyQualify</ExpandUsingDirectives><SA1212PropertyAccessorsMustFollowOrder>True</SA1212PropertyAccessorsMustFollowOrder><SA1213EventAccessorsMustFollowOrder>True</SA1213EventAccessorsMustFollowOrder></StyleCop.Ordering><StyleCop.Readability><SA1100DoNotPrefixCallsWithBaseUnlessLocalImplementationExists>True</SA1100DoNotPrefixCallsWithBaseUnlessLocalImplementationExists><SA1106CodeMustNotContainEmptyStatements>True</SA1106CodeMustNotContainEmptyStatements><SA1108BlockStatementsMustNotContainEmbeddedComments>True</SA1108BlockStatementsMustNotContainEmbeddedComments><SA1109BlockStatementsMustNotContainEmbeddedRegions>True</SA1109BlockStatementsMustNotContainEmbeddedRegions><SA1120CommentsMustContainText>True</SA1120CommentsMustContainText><SA1121UseBuiltInTypeAlias>True</SA1121UseBuiltInTypeAlias><SA1122UseStringEmptyForEmptyStrings>True</SA1122UseStringEmptyForEmptyStrings><SA1123DoNotPlaceRegionsWithinElements>True</SA1123DoNotPlaceRegionsWithinElements><SA1124CodeMustNotContainEmptyRegions>True</SA1124CodeMustNotContainEmptyRegions></StyleCop.Readability><StyleCop.Spacing><SA1001CommasMustBeSpacedCorrectly>True</SA1001CommasMustBeSpacedCorrectly><SA1005SingleLineCommentsMustBeginWithSingleSpace>True</SA1005SingleLineCommentsMustBeginWithSingleSpace><SA1006PreprocessorKeywordsMustNotBePrecededBySpace>True</SA1006PreprocessorKeywordsMustNotBePrecededBySpace><SA1021NegativeSignsMustBeSpacedCorrectly>True</SA1021NegativeSignsMustBeSpacedCorrectly><SA1022PositiveSignsMustBeSpacedCorrectly>True</SA1022PositiveSignsMustBeSpacedCorrectly><SA1025CodeMustNotContainMultipleWhitespaceInARow>True</SA1025CodeMustNotContainMultipleWhitespaceInARow></StyleCop.Spacing></Profile> + <?xml version="1.0" encoding="utf-16"?><Profile name="StyleCop"><CSArrangeThisQualifier>True</CSArrangeThisQualifier><CSOptimizeUsings><OptimizeUsings>True</OptimizeUsings><EmbraceInRegion>True</EmbraceInRegion><RegionName></RegionName></CSOptimizeUsings><CSReformatCode>True</CSReformatCode><CSReorderTypeMembers>True</CSReorderTypeMembers><StyleCop.Documentation><SA1600ElementsMustBeDocumented>False</SA1600ElementsMustBeDocumented><SA1604ElementDocumentationMustHaveSummary>False</SA1604ElementDocumentationMustHaveSummary><SA1609PropertyDocumentationMustHaveValueDocumented>False</SA1609PropertyDocumentationMustHaveValueDocumented><SA1611ElementParametersMustBeDocumented>False</SA1611ElementParametersMustBeDocumented><SA1615ElementReturnValueMustBeDocumented>False</SA1615ElementReturnValueMustBeDocumented><SA1617VoidReturnValueMustNotBeDocumented>False</SA1617VoidReturnValueMustNotBeDocumented><SA1618GenericTypeParametersMustBeDocumented>False</SA1618GenericTypeParametersMustBeDocumented><SA1626SingleLineCommentsMustNotUseDocumentationStyleSlashes>False</SA1626SingleLineCommentsMustNotUseDocumentationStyleSlashes><SA1628DocumentationTextMustBeginWithACapitalLetter>False</SA1628DocumentationTextMustBeginWithACapitalLetter><SA1629DocumentationTextMustEndWithAPeriod>False</SA1629DocumentationTextMustEndWithAPeriod><SA1633SA1641UpdateFileHeader>False</SA1633SA1641UpdateFileHeader><SA1639FileHeaderMustHaveSummary>False</SA1639FileHeaderMustHaveSummary><SA1642ConstructorSummaryDocumentationMustBeginWithStandardText>False</SA1642ConstructorSummaryDocumentationMustBeginWithStandardText><SA1643DestructorSummaryDocumentationMustBeginWithStandardText>False</SA1643DestructorSummaryDocumentationMustBeginWithStandardText><SA1644DocumentationHeadersMustNotContainBlankLines>False</SA1644DocumentationHeadersMustNotContainBlankLines></StyleCop.Documentation><StyleCop.Layout><SA1500CurlyBracketsForMultiLineStatementsMustNotShareLine>True</SA1500CurlyBracketsForMultiLineStatementsMustNotShareLine><SA1509OpeningCurlyBracketsMustNotBePrecededByBlankLine>True</SA1509OpeningCurlyBracketsMustNotBePrecededByBlankLine><SA1510ChainedStatementBlocksMustNotBePrecededByBlankLine>True</SA1510ChainedStatementBlocksMustNotBePrecededByBlankLine><SA1511WhileDoFooterMustNotBePrecededByBlankLine>True</SA1511WhileDoFooterMustNotBePrecededByBlankLine><SA1512SingleLineCommentsMustNotBeFollowedByBlankLine>True</SA1512SingleLineCommentsMustNotBeFollowedByBlankLine><SA1513ClosingCurlyBracketMustBeFollowedByBlankLine>True</SA1513ClosingCurlyBracketMustBeFollowedByBlankLine><SA1514ElementDocumentationHeaderMustBePrecededByBlankLine>True</SA1514ElementDocumentationHeaderMustBePrecededByBlankLine><SA1515SingleLineCommentMustBeProceededByBlankLine>True</SA1515SingleLineCommentMustBeProceededByBlankLine></StyleCop.Layout><StyleCop.Maintainability><SA1119StatementMustNotUseUnnecessaryParenthesis>True</SA1119StatementMustNotUseUnnecessaryParenthesis></StyleCop.Maintainability><StyleCop.Ordering><AlphabeticalUsingDirectives>Alphabetical</AlphabeticalUsingDirectives><ExpandUsingDirectives>FullyQualify</ExpandUsingDirectives><SA1212PropertyAccessorsMustFollowOrder>True</SA1212PropertyAccessorsMustFollowOrder><SA1213EventAccessorsMustFollowOrder>True</SA1213EventAccessorsMustFollowOrder></StyleCop.Ordering><StyleCop.Readability><SA1100DoNotPrefixCallsWithBaseUnlessLocalImplementationExists>True</SA1100DoNotPrefixCallsWithBaseUnlessLocalImplementationExists><SA1106CodeMustNotContainEmptyStatements>True</SA1106CodeMustNotContainEmptyStatements><SA1108BlockStatementsMustNotContainEmbeddedComments>True</SA1108BlockStatementsMustNotContainEmbeddedComments><SA1109BlockStatementsMustNotContainEmbeddedRegions>True</SA1109BlockStatementsMustNotContainEmbeddedRegions><SA1120CommentsMustContainText>True</SA1120CommentsMustContainText><SA1121UseBuiltInTypeAlias>True</SA1121UseBuiltInTypeAlias><SA1122UseStringEmptyForEmptyStrings>True</SA1122UseStringEmptyForEmptyStrings><SA1123DoNotPlaceRegionsWithinElements>True</SA1123DoNotPlaceRegionsWithinElements><SA1124CodeMustNotContainEmptyRegions>True</SA1124CodeMustNotContainEmptyRegions></StyleCop.Readability><StyleCop.Spacing><SA1001CommasMustBeSpacedCorrectly>True</SA1001CommasMustBeSpacedCorrectly><SA1005SingleLineCommentsMustBeginWithSingleSpace>True</SA1005SingleLineCommentsMustBeginWithSingleSpace><SA1006PreprocessorKeywordsMustNotBePrecededBySpace>True</SA1006PreprocessorKeywordsMustNotBePrecededBySpace><SA1021NegativeSignsMustBeSpacedCorrectly>True</SA1021NegativeSignsMustBeSpacedCorrectly><SA1022PositiveSignsMustBeSpacedCorrectly>True</SA1022PositiveSignsMustBeSpacedCorrectly><SA1025CodeMustNotContainMultipleWhitespaceInARow>True</SA1025CodeMustNotContainMultipleWhitespaceInARow></StyleCop.Spacing></Profile> StyleCop - AutoQACleanupCode + StyleCop All True True @@ -455,7 +455,13 @@ <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> <Policy Inspect="True" Prefix="T" Suffix="" Style="AaBb" /> <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> + True + D:\Projects\windows-universal-app-driver\Winium\Winium.sln.DotSettings + + True + 1 True True True - True \ No newline at end of file + True + False \ No newline at end of file