()
| 97 | } |
| 98 | |
| 99 | export default async function bisectFeatures(): Promise<Record<string, boolean> | void> { |
| 100 | // `bisect` stores the list of features to be split in half |
| 101 | const bisectedFeatures = await state.get(); |
| 102 | if (!bisectedFeatures) { |
| 103 | return; |
| 104 | } |
| 105 | |
| 106 | console.log(`Bisecting ${bisectedFeatures.length} features:\n${bisectedFeatures.join('\n')}`); |
| 107 | |
| 108 | const steps = Math.ceil(Math.log2(Math.max(bisectedFeatures.length))) + 1; |
| 109 | await elementReady('body'); |
| 110 | createMessageBox( |
| 111 | `Do you see the change or issue? (${pluralize(steps, 'last step', '$$ steps remaining')})`, |
| 112 | <div> |
| 113 | <button type="button" className="btn btn-danger mr-2 tmp-mr-2" value="no" aria-disabled="true" onClick={onChoiceButtonClick}> |
| 114 | No |
| 115 | </button> |
| 116 | <button type="button" className="btn btn-primary" value="yes" aria-disabled="true" onClick={onChoiceButtonClick}> |
| 117 | Yes |
| 118 | </button> |
| 119 | </div>, |
| 120 | ); |
| 121 | |
| 122 | // Enable "Yes"/"No" buttons once the page is done loading |
| 123 | if (document.readyState === 'complete') { |
| 124 | enableButtons(); |
| 125 | } else { |
| 126 | window.addEventListener('load', enableButtons); |
| 127 | } |
| 128 | |
| 129 | // Hide message when the process is done elsewhere |
| 130 | globalThis.addEventListener('visibilitychange', hideMessage); |
| 131 | |
| 132 | const half = getMiddleStep(bisectedFeatures); |
| 133 | const temporaryOptions: Record<string, boolean> = {}; |
| 134 | for (const feature of importedFeatures) { |
| 135 | const index = bisectedFeatures.indexOf(feature); |
| 136 | temporaryOptions[`feature:${feature}`] = index !== -1 && index < half; |
| 137 | } |
| 138 | |
| 139 | console.log({temporaryOptions}); |
| 140 | return temporaryOptions; |
| 141 | } |
no test coverage detected