(xcuserstatePath: string)
| 104 | * @returns Extracted scheme and simulator information |
| 105 | */ |
| 106 | export function parseXcuserstate(xcuserstatePath: string): XcodeStateResult { |
| 107 | const result: XcodeStateResult = {}; |
| 108 | |
| 109 | try { |
| 110 | const buffer = readFileSync(xcuserstatePath); |
| 111 | const [root] = bplistParseBuffer(buffer) as [BplistResult]; |
| 112 | |
| 113 | if (!root || root.$archiver !== 'NSKeyedArchiver' || !Array.isArray(root.$objects)) { |
| 114 | return result; |
| 115 | } |
| 116 | |
| 117 | const objects = root.$objects; |
| 118 | |
| 119 | // Find key indices |
| 120 | const activeSchemeIdx = findStringIndex(objects, 'ActiveScheme'); |
| 121 | const activeRunDestIdx = findStringIndex(objects, 'ActiveRunDestination'); |
| 122 | const ideNameStringIdx = findStringIndex(objects, 'IDENameString'); |
| 123 | const targetDeviceLocationIdx = findStringIndex(objects, 'targetDeviceLocation'); |
| 124 | |
| 125 | if (activeSchemeIdx === -1 && activeRunDestIdx === -1) { |
| 126 | return result; |
| 127 | } |
| 128 | |
| 129 | // Find the dictionary containing ActiveScheme key |
| 130 | const parentDict = findDictWithKey(objects, activeSchemeIdx); |
| 131 | if (!parentDict) { |
| 132 | return result; |
| 133 | } |
| 134 | |
| 135 | // Extract scheme name: ActiveScheme -> { IDENameString -> "SchemeName" } |
| 136 | if (activeSchemeIdx !== -1 && ideNameStringIdx !== -1) { |
| 137 | const schemeObj = getValueForKey(objects, parentDict, activeSchemeIdx); |
| 138 | if (typeof schemeObj === 'object' && schemeObj !== null) { |
| 139 | const schemeDict = schemeObj as ArchivedDict; |
| 140 | const schemeName = getValueForKey(objects, schemeDict, ideNameStringIdx); |
| 141 | if (typeof schemeName === 'string') { |
| 142 | result.scheme = schemeName; |
| 143 | } |
| 144 | } |
| 145 | } |
| 146 | |
| 147 | // Extract run destination: ActiveRunDestination -> { targetDeviceLocation -> "dvtdevice-..." } |
| 148 | if (activeRunDestIdx !== -1 && targetDeviceLocationIdx !== -1) { |
| 149 | const destObj = getValueForKey(objects, parentDict, activeRunDestIdx); |
| 150 | if (typeof destObj === 'object' && destObj !== null) { |
| 151 | const destDict = destObj as ArchivedDict; |
| 152 | const location = getValueForKey(objects, destDict, targetDeviceLocationIdx); |
| 153 | if (typeof location === 'string') { |
| 154 | result.deviceLocation = location; |
| 155 | |
| 156 | // Extract UUID from location string: "dvtdevice-iphonesimulator:UUID" |
| 157 | const match = location.match(/dvtdevice-([a-z]+):([A-F0-9-]{36})/i); |
| 158 | if (match) { |
| 159 | result.simulatorPlatform = match[1]; |
| 160 | result.simulatorId = match[2]; |
| 161 | } |
| 162 | } |
| 163 | } |
no test coverage detected