@@ -263,14 +263,33 @@ def _normalize_element_data(self, raw_data: Any) -> Dict[str, Any]:
263263
264264 # If it's already a dict from selector_map or interactive_elements
265265 if isinstance (raw_data , dict ):
266+ # Extract tag name first
267+ tag_name = raw_data .get ('tag_name' ) or raw_data .get ('node_name' ) or ''
268+
269+ # Extract text value from multiple possible fields, filtering out browser-use bugs
270+ text_value = ''
271+ for text_field in ['text' , 'inner_text' , 'textContent' , 'innerText' , 'node_value' ]:
272+ potential_text = raw_data .get (text_field , '' ).strip ()
273+ if potential_text :
274+ # IMPORTANT: browser-use sometimes provides JavaScript href as 'text' for anchor tags
275+ # Skip this and try other fields (case-insensitive check)
276+ if tag_name == 'a' and potential_text .lower ().startswith ('javascript:' ):
277+ continue
278+ text_value = potential_text
279+ break
280+
266281 # Extract common fields with fallbacks
267282 result = {
268- 'node_name' : raw_data . get ( ' tag_name' ) or raw_data . get ( 'node_name' ) or '' ,
269- 'node_value' : raw_data . get ( 'text' ) or raw_data . get ( 'node_value' ) or '' ,
283+ 'node_name' : tag_name ,
284+ 'node_value' : text_value ,
270285 'attributes' : raw_data .get ('attributes' , {}),
271286 'xpath' : raw_data .get ('xpath' ) or raw_data .get ('x_path' ) or '' ,
272287 }
273288
289+ # IMPORTANT: Preserve selector_strategies for semantic/deterministic element finding
290+ if 'selector_strategies' in raw_data :
291+ result ['selector_strategies' ] = raw_data ['selector_strategies' ]
292+
274293 # Compute element hash if we have the data
275294 tag_name = result ['node_name' ].lower ()
276295 # Use xpath or a combination of attributes as hash source
@@ -389,10 +408,10 @@ def _convert_action_to_step(
389408
390409 Mapping (browser-use action names):
391410 - navigate → navigation step
392- - input_text → input step with target_text
393- - click → click step with target_text
411+ - input, input_text → input step with target_text
412+ - click, click_element → click step with target_text
394413 - send_keys → keypress step
395- - extract_content → extract_page_content step
414+ - extract, extract_content, extract_page_content → extract_page_content step
396415 - scroll → scroll step
397416 """
398417 agent_context = agent_context or {}
@@ -412,8 +431,8 @@ def _convert_action_to_step(
412431
413432 return step
414433
415- # Input text actions
416- elif action_type == ' input_text' :
434+ # Input text actions (browser-use can use either 'input' or 'input_text')
435+ elif action_type in [ 'input' , ' input_text'] :
417436 target_text = self ._extract_target_text (element_data , action_dict )
418437 # Ensure target_text is never empty
419438 if not target_text :
@@ -502,10 +521,16 @@ def _convert_action_to_step(
502521
503522 return step
504523
505- # Extract content actions
506- elif action_type in ['extract_page_content' , 'extract_content' ]:
524+ # Extract content actions (browser-use can use 'extract', 'extract_content', or 'extract_page_content')
525+ elif action_type in ['extract' , ' extract_page_content' , 'extract_content' ]:
507526 # Browser-use may use different field names for extraction goal
508- goal = action_dict .get ('value' ) or action_dict .get ('goal' ) or action_dict .get ('content' ) or 'page content'
527+ goal = (
528+ action_dict .get ('value' )
529+ or action_dict .get ('goal' )
530+ or action_dict .get ('content' )
531+ or action_dict .get ('query' )
532+ or 'page content'
533+ )
509534 return {
510535 'type' : 'extract_page_content' ,
511536 'goal' : goal ,
0 commit comments