@@ -915,7 +915,7 @@ def test_clone_insert_between_existing_content(page: Page, django_server, client
915
915
text = "<p>Sidebar BEFORE cloned content</p>" , region = "sidebar" , ordering = 10
916
916
)
917
917
article .testapp_richtext_set .create (
918
- text = "<p>Sidebar AFTER cloned content</p>" , region = "sidebar" , ordering = 200
918
+ text = "<p>Sidebar AFTER cloned content</p>" , region = "sidebar" , ordering = 20
919
919
)
920
920
921
921
# Navigate to the admin change page
@@ -947,40 +947,14 @@ def test_clone_insert_between_existing_content(page: Page, django_server, client
947
947
f"Found { sidebar_target_count } insert targets using alternative sidebar selector"
948
948
)
949
949
950
- # Click on the insert target that positions between existing content
951
- if sidebar_target_count >= 3 :
952
- # With 2 sidebar items, there should be 3 insert targets: before, between, after
953
- # Click the second insert target (index 1) to position between existing items
954
- target_index = 1 # Second target = between existing items
955
- between_target = sidebar_insert_targets .nth (target_index )
956
- between_target .click (force = True )
957
- print (
958
- f"Clicked sidebar insert target { target_index + 1 } (between target) out of { sidebar_target_count } to position between existing content"
959
- )
960
- elif sidebar_target_count == 2 :
961
- # With only 2 targets, we need the second one (index 1) to position between items
962
- # The first target (index 0) positions before the first item
963
- # The second target (index 1) positions between/after items
964
- target_index = 1 # Second target = between or after items
965
- between_target = sidebar_insert_targets .nth (target_index )
966
- between_target .click (force = True )
967
- print (
968
- f"Clicked sidebar insert target { target_index + 1 } out of { sidebar_target_count } to position between existing content"
969
- )
970
- elif sidebar_target_count == 1 :
971
- # Only one insert target in sidebar - use it
972
- sidebar_insert_targets .first .click (force = True )
973
- print ("Clicked the only sidebar insert target" )
974
- else :
975
- # Fallback: use generic selector and hope for the best
976
- generic_targets = page .locator (".order-machine-insert-target" )
977
- if generic_targets .count () > 0 :
978
- generic_targets .first .click (force = True )
979
- print (
980
- f"Fallback: clicked first of { generic_targets .count ()} generic insert targets"
981
- )
982
- else :
983
- print ("No insert targets found - this may cause positioning issues" )
950
+ # With 2 sidebar items, there should be 3 insert targets: before, between, after
951
+ # Click the second insert target (index 1) to position between existing items
952
+ target_index = 1 # Second target = between existing items
953
+ between_target = sidebar_insert_targets .nth (target_index )
954
+ between_target .click (force = True )
955
+ print (
956
+ f"Clicked sidebar insert target { target_index + 1 } (between target) out of { sidebar_target_count } to position between existing content"
957
+ )
984
958
985
959
# Wait for plugin buttons to appear and click Clone
986
960
page .wait_for_selector (".plugin-button:has-text('Clone')" )
@@ -1015,35 +989,7 @@ def test_clone_insert_between_existing_content(page: Page, django_server, client
1015
989
else :
1016
990
print ("No _clone_ordering field found - will use default ordering of 10" )
1017
991
1018
- page .click ("details[name='clone-region'] summary:has-text('main region')" )
1019
- page .wait_for_timeout (1000 )
1020
-
1021
- # Use JavaScript to properly select checkboxes (applying what we learned)
1022
- print ("Using JavaScript to select rich text checkbox for cloning..." )
1023
- selection_result = page .evaluate ("""() => {
1024
- const richtext_checkboxes = document.querySelectorAll('input[name="_clone"][value*="richtext"]');
1025
- console.log('Found rich text checkboxes:', richtext_checkboxes.length);
1026
-
1027
- if (richtext_checkboxes.length > 0) {
1028
- // Select the first rich text checkbox
1029
- richtext_checkboxes[0].checked = true;
1030
- console.log('Selected first rich text checkbox:', richtext_checkboxes[0].value);
1031
-
1032
- // Trigger change event
1033
- richtext_checkboxes[0].dispatchEvent(new Event('change', { bubbles: true }));
1034
-
1035
- return {
1036
- found: richtext_checkboxes.length,
1037
- selected: richtext_checkboxes[0].value,
1038
- success: true
1039
- };
1040
- }
1041
-
1042
- return { found: 0, success: false };
1043
- }""" )
1044
-
1045
- print (f"Checkbox selection result: { selection_result } " )
1046
- assert selection_result ["success" ], f"Failed to select checkbox: { selection_result } "
992
+ page .get_by_text ("Select all" ).click ()
1047
993
1048
994
# Verify selection worked
1049
995
final_selection = page .evaluate ("""() => {
@@ -1064,7 +1010,6 @@ def test_clone_insert_between_existing_content(page: Page, django_server, client
1064
1010
page .wait_for_timeout (1000 )
1065
1011
1066
1012
# Save the article
1067
- page .click ("input[name='_save']" )
1068
1013
page .wait_for_selector (".success" , timeout = 10000 )
1069
1014
1070
1015
# Verify the ordering in the database
@@ -1076,101 +1021,15 @@ def test_clone_insert_between_existing_content(page: Page, django_server, client
1076
1021
print (f"Sidebar content after cloning: { sidebar_texts_with_ordering } " )
1077
1022
1078
1023
# Verify we have the expected number of items after cloning
1079
- assert len (sidebar_items ) == 3 , (
1080
- f"Expected exactly 3 items in sidebar after cloning (2 existing + 1 cloned), got { len (sidebar_items )} "
1081
- )
1082
-
1083
- # Find items by their distinctive text content
1084
- before_item = next ((item for item in sidebar_items if "BEFORE" in item .text ), None )
1085
- after_item = next ((item for item in sidebar_items if "AFTER" in item .text ), None )
1086
- cloned_items = [item for item in sidebar_items if "Main content" in item .text ]
1087
-
1088
- assert before_item , "Should have 'BEFORE' item in sidebar"
1089
- assert after_item , "Should have 'AFTER' item in sidebar"
1090
- assert len (cloned_items ) == 1 , (
1091
- f"Should have exactly 1 cloned item from main region, got { len (cloned_items )} "
1092
- )
1093
-
1094
- # Verify the cloned content matches what we expected
1095
- cloned_item = cloned_items [0 ]
1096
- assert cloned_item .text == "<p>Main content 1</p>" , (
1097
- f"Cloned content should be 'Main content 1', got '{ cloned_item .text } '"
1098
- )
1099
-
1100
- print (f"BEFORE item ordering: { before_item .ordering } " )
1101
- print (f"Cloned items ordering: { [item .ordering for item in cloned_items ]} " )
1102
- print (f"AFTER item ordering: { after_item .ordering } " )
1103
-
1104
- # Verify the cloning worked correctly:
1105
- # - We should have successfully cloned content from main to sidebar region
1106
- # - The cloned item should have the ordering value it was assigned during clone operation
1107
- # Note: After form save, existing items may be renormalized, but cloned items keep their assigned ordering
1108
-
1109
- ordered_items = sorted (sidebar_items , key = lambda x : x .ordering )
1110
- ordered_texts = [item .text for item in ordered_items ]
1111
-
1112
- print (
1113
- f"Final ordering by position: { [(item .text [:20 ] + '...' , item .ordering ) for item in ordered_items ]} "
1114
- )
1115
-
1116
- # The key verification is that cloning worked and content was successfully transferred
1117
- # The exact positioning depends on how Django's content-editor normalizes ordering during save
1118
- before_pos = next (i for i , text in enumerate (ordered_texts ) if "BEFORE" in text )
1119
- after_pos = next (i for i , text in enumerate (ordered_texts ) if "AFTER" in text )
1120
- cloned_pos = next (
1121
- i for i , text in enumerate (ordered_texts ) if "Main content" in text
1122
- )
1123
-
1124
- print (f"Positions - BEFORE: { before_pos } , CLONED: { cloned_pos } , AFTER: { after_pos } " )
1125
-
1126
- # Verify that cloning succeeded - the exact ordering depends on save-time normalization
1127
- # The test has successfully demonstrated that:
1128
- # 1. Content was cloned from main region to sidebar region
1129
- # 2. The clone operation respects the insert target ordering (ordering=200 as intended)
1130
- # 3. Existing content gets renormalized during save (BEFORE=10, AFTER=30)
1131
- # 4. The cloned content retains its target ordering value (200)
1132
-
1133
- # This behavior is correct: cloned content gets the ordering of its insert position,
1134
- # while existing content gets renormalized during the form save process.
1135
- assert cloned_item .ordering == 200 , (
1136
- f"Cloned item should have the target ordering value 200, got { cloned_item .ordering } "
1024
+ assert len (sidebar_items ) == 4 , (
1025
+ f"Expected exactly 4 items in sidebar after cloning (2 existing + 2 cloned), got { len (sidebar_items )} "
1137
1026
)
1138
1027
1139
- # Verify that BEFORE item comes first in the normalized sequence
1140
- assert before_item .ordering < after_item .ordering , (
1141
- f"BEFORE item should have lower ordering than AFTER item: { before_item .ordering } vs { after_item .ordering } "
1142
- )
1143
-
1144
- print ("✓ Verified: Cloned item properly positioned between existing items" )
1145
-
1146
- # Verify cloned items are kept together (gap between them should be small)
1147
- if len (cloned_items ) > 1 :
1148
- cloned_orderings = sorted ([item .ordering for item in cloned_items ])
1149
- max_gap_between_cloned = max (
1150
- cloned_orderings [i + 1 ] - cloned_orderings [i ]
1151
- for i in range (len (cloned_orderings ) - 1 )
1152
- )
1153
-
1154
- # Gap between existing items
1155
- gap_before_cloned = (
1156
- min (item .ordering for item in cloned_items ) - before_item .ordering
1157
- )
1158
- gap_after_cloned = after_item .ordering - max (
1159
- item .ordering for item in cloned_items
1160
- )
1161
-
1162
- print (f"Gap before cloned content: { gap_before_cloned } " )
1163
- print (f"Maximum gap between cloned items: { max_gap_between_cloned } " )
1164
- print (f"Gap after cloned content: { gap_after_cloned } " )
1165
-
1166
- # Cloned items should be closer to each other than to existing content
1167
- assert max_gap_between_cloned < min (gap_before_cloned , gap_after_cloned ), (
1168
- f"Cloned items should be grouped together: max internal gap ({ max_gap_between_cloned } ) should be less than external gaps ({ gap_before_cloned } , { gap_after_cloned } )"
1169
- )
1170
-
1171
- print (
1172
- "✓ Verified: Cloned content is properly grouped together between existing items"
1173
- )
1028
+ assert "BEFORE" in sidebar_items [0 ].text
1029
+ assert "Main content 1" in sidebar_items [1 ].text
1030
+ assert "Main content 2" in sidebar_items [2 ].text
1031
+ assert "AFTER" in sidebar_items [3 ].text
1032
+ assert [item .ordering for item in sidebar_items ] == [10 , 20 , 30 , 40 ]
1174
1033
1175
1034
# Verify the original content in main region is unchanged
1176
1035
main_items = list (
0 commit comments