3

私は、エンタープライズ アプリケーションの iOS デバイスとシミュレーターで、より高度な自動化を行っています。自動化は、ブラウザレス Javascript で記述されています。メソッドの 1 つはデバイスでは機能しますが、シミュレーターでは機能しないため、回避策をコーディングする必要があります。興味深いことに、これは UIATarget.localTarget().frontMostApp().preferencesValueForKey(key) です。

必要なことは、ディスク上の plist ファイルからサーバーへのパス (さまざま) を読み取ることです。シミュレーターでの回避策として、次の行を使用して、設定を含む plist ファイルを見つけました。

// Get the alias of the user who's logged in
var result = UIATarget.localTarget().host().performTaskWithPathArgumentsTimeout("/usr/bin/whoami", [], 5).stdout;

// Remove the extra newline at the end of the alias we got
result = result.replace('\n',"");

// Find the location of the plist containing the server info
result = UIATarget.localTarget().host().performTaskWithPathArgumentsTimeout("/usr/bin/find", ["/Users/"+result+"/Library/Application Support/iPhone Simulator", "-name", "redacted.plist"], 100);

// For some reason we need a delay here
UIATarget.localTarget().delay(.5);

// Results are returned in a single string separated by newline characters, so we can split it into an array
// This array contains all of the folders which have the plist file under the Simulator directory
var plistLocations = result.stdout.split("\n");

...

// For this example, let's just assume we want slot 0 here to save time
var plistBinaryLocation = plistLocations[0];
var plistXMLLocation =  plistLocations[i] + ".xml";
result = UIATarget.localTarget().host().performTaskWithPathArgumentsTimeout("/usr/bin/plutil", ["-convert","xml1", plistBinaryLocation,"-o", plistXMLLocation], 100);

ここから、コンテンツを取得する最善の方法は、ファイルを cat または grep することだと思います。ディスクから直接ファイルを読み取ることはできないからです。ただし、構文を取得するのに問題があります。私が読んでいるplistファイルの編集されたスニペットは次のとおりです。

<key>server_url</key>
<string>http://pathToServer</string>

ファイルには多数のキー/文字列のペアがあり、server_url キーは一意です。理想的には、ルックバックのようなことをしたいのですが、JavaScript がそれをサポートしていないように見えるので、ファイルからペアを取得し、少し後で削り取ることにしました。

これでキーを検索できます:

// This line works
var expression = new RegExp(escapeRegExp("<key>server_url</key>"));

if(result.stdout.match(expression))
{
    UIALogger.logMessage("FOUND IT!!!");
}
else
{
    UIALogger.logMessage("NOPE :(");
}

escapeRegExp メソッドは次のようになります。

function escapeRegExp(str) 
{
    var result =  str.replace(/([()[{*+.$^\\|?])/g, '\\$1');

    UIALogger.logMessage("NEW STRING: " + result);
    return result;
}

また、この行は値を返します (ただし、間違った行を取得します)。

var expression = new RegExp(escapeRegExp("<string>(.*?)</string>"));

ただし、この 2 つを組み合わせると、(正規表現構文) は端末では機能しますが、コードでは機能しません。

var expression = new RegExp(escapeRegExp("<key>server_url</key>[\s]*<string>(.*?)</string>"));

私は何が欠けていますか?私もgrepとegrepを試してみましたが、うまくいきませんでした。

4

1 に答える 1

1

JavaScript コードで正規表現を機能させるには、2 つの問題があります。

  • まず、正規表現文字列全体をエスケープしています。つまり、キャプチャ(.*?)と空白の無視[\s]*もエスケープされ、期待どおりに評価されません。XML 部分をエスケープし、エスケープせずに正規表現部分を追加する必要があります。
  • 2 つ目は、空白を無視する部分[\s]*が、JavaScript の通常の文字列エスケープ規則の犠牲になっていることです。出力で「\s」が「s」に変わります。そのバックスラッシュを「\s」でエスケープして、正規表現を作成するために渡す文字列で「\s」のままにする必要があります。

UI オートメーション エンジン自体で検証した動作スクリプトを作成しました。予想される URL を抽出して出力する必要があります。

var testString = "" +
"<plistExample>\n" +
"   <key>dont-find-me</key>\n" +
"   <string>bad value</string>\n" +
"   <key>server_url</key>\n" +
"   <string>http://server_url</string>\n" +
"</plistExample>";

function escapeRegExp(str) 
{
    var result =  str.replace(/([()[{*+.$^\\|?])/g, '\\$1');

    UIALogger.logMessage("NEW STRING: " + result);
    return result;
}

var strExp = escapeRegExp("<key>server_url</key>") + "[\\s]*" + escapeRegExp("<string>") + "(.*)" + escapeRegExp("</string>");

UIALogger.logMessage("Expression escaping only the xml parts:" + strExp);

var exp = new RegExp(strExp);
var match = testString.match(exp);

UIALogger.logMessage("Match: " + match[1]);

ただし、正規表現でエスケープする必要があるのは、XML 終了タグのスラッシュだけであることを指摘しておく必要があります。つまり、escapeRegExp()関数は必要なく、次のように必要な式を記述できます。

var exp = new RegExp("<key>server_url<\/key>[\\s]*<string>(.*)<\/string>");
于 2013-07-15T13:31:48.267 に答える