エディタがフォーカス済みの場合のクリック操作を回避
要素が既にアクティブな場合、simulate_first_action_if_needed のクリック操作が意図しない場所に選択範囲を移動させる問題を修正しました。この変更により、エディタが既にフォーカスされている状態でのテスト実行時に、不必要なクリック操作によるカーソル移動が防止されます。
背景
Lexxyのテストヘルパー EditorHandler は、テキスト入力や選択範囲の操作前に simulate_first_interaction_if_needed メソッドでエディタのクリック操作をシミュレートしていました。この操作はエディタが未フォーカス状態からの操作を可能にするためのものでしたが、既にフォーカス済みの場合にも無条件に実行されていました。
テーブルのテストケースでは、この不要なクリック操作により選択範囲が別のセルに移動してしまう問題が顕在化しました。ヘッダーセル(th)に入力したテキストが、意図せずデータセル(td)として認識される状態になっていました。
技術的な変更
変更前:
def simulate_first_interaction_if_needed
# Adding text or selecting text will not work otherwise
unless @first_interaction_simulated
content_element.click
@first_interaction_simulated = true
end
end
変更後:
def simulate_first_interaction_if_needed
# Adding text or selecting text will not work otherwise
unless @first_interaction_simulated || content_element_active?
content_element.click
@first_interaction_simulated = true
end
end
def content_element_active?
active_element == content_element
end
def active_element
page.evaluate_script "document.activeElement"
end
content_element_active? メソッドが追加され、document.activeElement とエディタの content_element を比較してフォーカス状態を判定します。simulate_first_interaction_if_needed の条件式に content_element_active? が追加されたことで、エディタが既にアクティブな場合はクリック操作がスキップされます。
テーブルテストの修正では、セレクタの期待値が td から th に変更されました:
within_table do
assert_selector "th", text: "Test Cell"
end
これは、ヘッダーセルに入力したテキストが正しく th 要素として検証されるべき状態を反映しています。
設計判断
フォーカス状態の確認を追加する方式 が採用されました。@first_interaction_simulated フラグによる状態管理は維持しつつ、実際のDOM状態との照合を加えています。
document.activeElement を直接参照することで、テストコード側の状態フラグとブラウザの実際の状態の両方を考慮した判定になりました。これにより、フラグの初期化タイミングに依存せず、現在のフォーカス状態に基づいた動作が保証されます。
条件式を && ではなく || で結合することで、「既にクリック済み」または「既にフォーカス済み」のいずれかが真ならクリックをスキップする論理構造になっています。この設計により、テスト実行時の様々なコンテキストでのエディタ状態に対応できます。
まとめ
本PRは、エディタのフォーカス状態を考慮してクリック操作を制御する変更です。DOM状態の確認ロジックを追加することで、既にフォーカス済みのエディタへの不要な操作を回避し、テーブルセルなどでの選択範囲の意図しない移動を防止しています。