diff --git a/.gitignore b/.gitignore index f8fb8b4..a7b6488 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,5 @@ dist npm-debug.log src/livesplit_core.wasm src/livesplit-core + +test/screenshots diff --git a/test/layouts/all_components.ls1l b/test/layouts/all_components.ls1l new file mode 100644 index 0000000..bf8ad09 --- /dev/null +++ b/test/layouts/all_components.ls1l @@ -0,0 +1,520 @@ +{ + "components": [ + { + "CurrentComparison": { + "background": { + "Vertical": [ + [ + 1, + 1, + 1, + 0.06 + ], + [ + 1, + 1, + 1, + 0.005 + ] + ] + }, + "display_two_rows": false, + "label_color": null, + "value_color": null + } + }, + { + "CurrentPace": { + "background": { + "Vertical": [ + [ + 1, + 1, + 1, + 0.06 + ], + [ + 1, + 1, + 1, + 0.005 + ] + ] + }, + "comparison_override": null, + "display_two_rows": false, + "label_color": null, + "value_color": null, + "accuracy": "Seconds" + } + }, + { + "Delta": { + "background": { + "Vertical": [ + [ + 1, + 1, + 1, + 0.06 + ], + [ + 1, + 1, + 1, + 0.005 + ] + ] + }, + "comparison_override": null, + "display_two_rows": false, + "label_color": null, + "drop_decimals": true, + "accuracy": "Tenths" + } + }, + { + "DetailedTimer": { + "background": "Transparent", + "comparison1": null, + "comparison2": "Best Segments", + "hide_second_comparison": false, + "timer": { + "background": "Transparent", + "timing_method": null, + "height": 40, + "color_override": null, + "show_gradient": true, + "digits_format": "SingleDigitSeconds", + "accuracy": "Hundredths", + "is_segment_timer": false + }, + "segment_timer": { + "background": "Transparent", + "timing_method": null, + "height": 25, + "color_override": [ + 0.6666667, + 0.6666667, + 0.6666667, + 1 + ], + "show_gradient": true, + "digits_format": "SingleDigitSeconds", + "accuracy": "Hundredths", + "is_segment_timer": true + }, + "display_icon": false, + "show_segment_name": false + } + }, + { + "Graph": { + "comparison_override": null, + "show_best_segments": false, + "live_graph": true, + "flip_graph": false, + "behind_background_color": [ + 0.4509804, + 0.15686275, + 0.15686275, + 1 + ], + "ahead_background_color": [ + 0.15686275, + 0.4509804, + 0.20392157, + 1 + ], + "grid_lines_color": [ + 0, + 0, + 0, + 0.15 + ], + "graph_lines_color": [ + 1, + 1, + 1, + 1 + ], + "partial_fill_color": [ + 1, + 1, + 1, + 0.25 + ], + "complete_fill_color": [ + 1, + 1, + 1, + 0.4 + ], + "height": 80 + } + }, + { + "PbChance": { + "background": { + "Vertical": [ + [ + 1, + 1, + 1, + 0.06 + ], + [ + 1, + 1, + 1, + 0.005 + ] + ] + }, + "display_two_rows": false, + "label_color": null, + "value_color": null + } + }, + { + "PossibleTimeSave": { + "background": { + "Vertical": [ + [ + 1, + 1, + 1, + 0.06 + ], + [ + 1, + 1, + 1, + 0.005 + ] + ] + }, + "comparison_override": null, + "display_two_rows": false, + "total_possible_time_save": false, + "label_color": null, + "value_color": null, + "accuracy": "Hundredths" + } + }, + { + "PreviousSegment": { + "background": { + "Vertical": [ + [ + 1, + 1, + 1, + 0.06 + ], + [ + 1, + 1, + 1, + 0.005 + ] + ] + }, + "comparison_override": null, + "display_two_rows": false, + "label_color": null, + "drop_decimals": true, + "accuracy": "Tenths", + "show_possible_time_save": false + } + }, + { + "SegmentTime": { + "background": { + "Vertical": [ + [ + 1, + 1, + 1, + 0.06 + ], + [ + 1, + 1, + 1, + 0.005 + ] + ] + }, + "comparison_override": null, + "display_two_rows": false, + "label_color": null, + "value_color": null, + "accuracy": "Hundredths" + } + }, + { + "Splits": { + "background": { + "Alternating": [ + [ + 0, + 0, + 0, + 0 + ], + [ + 1, + 1, + 1, + 0.04 + ] + ] + }, + "visual_split_count": 16, + "split_preview_count": 1, + "show_thin_separators": true, + "separator_last_split": true, + "always_show_last_split": true, + "fill_with_blank_space": true, + "display_two_rows": false, + "current_split_gradient": { + "Vertical": [ + [ + 0.2, + 0.4509804, + 0.95686275, + 1 + ], + [ + 0.08235294, + 0.20784314, + 0.45490196, + 1 + ] + ] + }, + "show_column_labels": false, + "columns": [ + { + "name": "Time", + "start_with": "ComparisonTime", + "update_with": "SplitTime", + "update_trigger": "OnEndingSegment", + "comparison_override": null, + "timing_method": null + }, + { + "name": "+/−", + "start_with": "Empty", + "update_with": "Delta", + "update_trigger": "Contextual", + "comparison_override": null, + "timing_method": null + } + ] + } + }, + { + "SumOfBest": { + "background": { + "Vertical": [ + [ + 1, + 1, + 1, + 0.06 + ], + [ + 1, + 1, + 1, + 0.005 + ] + ] + }, + "display_two_rows": false, + "label_color": null, + "value_color": null, + "accuracy": "Seconds" + } + }, + { + "Text": { + "background": { + "Vertical": [ + [ + 1, + 1, + 1, + 0.06 + ], + [ + 1, + 1, + 1, + 0.005 + ] + ] + }, + "display_two_rows": false, + "left_center_color": null, + "right_color": null, + "text": { + "Center": "" + } + } + }, + { + "Timer": { + "background": "Transparent", + "timing_method": null, + "height": 60, + "color_override": null, + "show_gradient": true, + "digits_format": "SingleDigitSeconds", + "accuracy": "Hundredths", + "is_segment_timer": false + } + }, + { + "Title": { + "background": { + "Vertical": [ + [ + 1, + 1, + 1, + 0.13 + ], + [ + 1, + 1, + 1, + 0 + ] + ] + }, + "text_color": null, + "show_game_name": true, + "show_category_name": true, + "show_finished_runs_count": false, + "show_attempt_count": true, + "text_alignment": "Auto", + "display_as_single_line": false, + "display_game_icon": true, + "show_region": false, + "show_platform": false, + "show_variables": true + } + }, + { + "TotalPlaytime": { + "background": { + "Vertical": [ + [ + 1, + 1, + 1, + 0.06 + ], + [ + 1, + 1, + 1, + 0.005 + ] + ] + }, + "display_two_rows": false, + "show_days": true, + "label_color": null, + "value_color": null + } + }, + { + "BlankSpace": { + "background": "Transparent", + "size": 24 + } + }, + "Separator" + ], + "general": { + "direction": "Vertical", + "background": { + "Plain": [ + 0.06, + 0.06, + 0.06, + 1 + ] + }, + "best_segment_color": [ + 1, + 0.8333333, + 0, + 1 + ], + "ahead_gaining_time_color": [ + 0, + 0.8, + 0.21333332, + 1 + ], + "ahead_losing_time_color": [ + 0.38000003, + 0.82000005, + 0.49733335, + 1 + ], + "behind_gaining_time_color": [ + 0.82000005, + 0.38000003, + 0.38000003, + 1 + ], + "behind_losing_time_color": [ + 0.8, + 0, + 0, + 1 + ], + "not_running_color": [ + 0.67, + 0.67, + 0.67, + 1 + ], + "personal_best_color": [ + 0.08000004, + 0.64733326, + 1, + 1 + ], + "paused_color": [ + 0.48, + 0.48, + 0.48, + 1 + ], + "thin_separators_color": [ + 1, + 1, + 1, + 0.09 + ], + "separators_color": [ + 1, + 1, + 1, + 0.35 + ], + "text_color": [ + 1, + 1, + 1, + 1 + ] + } +} \ No newline at end of file diff --git a/test/layouts/default.ls1l b/test/layouts/default.ls1l new file mode 100644 index 0000000..0271ff7 --- /dev/null +++ b/test/layouts/default.ls1l @@ -0,0 +1,212 @@ +{ + "components": [ + { + "Title": { + "background": { + "Vertical": [ + [ + 1, + 1, + 1, + 0.13 + ], + [ + 1, + 1, + 1, + 0 + ] + ] + }, + "text_color": null, + "show_game_name": true, + "show_category_name": true, + "show_finished_runs_count": false, + "show_attempt_count": true, + "text_alignment": "Auto", + "display_as_single_line": false, + "display_game_icon": true, + "show_region": false, + "show_platform": false, + "show_variables": true + } + }, + { + "Splits": { + "background": { + "Alternating": [ + [ + 0, + 0, + 0, + 0 + ], + [ + 1, + 1, + 1, + 0.04 + ] + ] + }, + "visual_split_count": 16, + "split_preview_count": 1, + "show_thin_separators": true, + "separator_last_split": true, + "always_show_last_split": true, + "fill_with_blank_space": true, + "display_two_rows": false, + "current_split_gradient": { + "Vertical": [ + [ + 0.2, + 0.4509804, + 0.95686275, + 1 + ], + [ + 0.08235294, + 0.20784314, + 0.45490196, + 1 + ] + ] + }, + "show_column_labels": false, + "columns": [ + { + "name": "Time", + "start_with": "ComparisonTime", + "update_with": "SplitTime", + "update_trigger": "OnEndingSegment", + "comparison_override": null, + "timing_method": null + }, + { + "name": "+/−", + "start_with": "Empty", + "update_with": "Delta", + "update_trigger": "Contextual", + "comparison_override": null, + "timing_method": null + } + ] + } + }, + { + "Timer": { + "background": "Transparent", + "timing_method": null, + "height": 60, + "color_override": null, + "show_gradient": true, + "digits_format": "SingleDigitSeconds", + "accuracy": "Hundredths", + "is_segment_timer": false + } + }, + { + "PreviousSegment": { + "background": { + "Vertical": [ + [ + 1, + 1, + 1, + 0.06 + ], + [ + 1, + 1, + 1, + 0.005 + ] + ] + }, + "comparison_override": null, + "display_two_rows": false, + "label_color": null, + "drop_decimals": true, + "accuracy": "Tenths", + "show_possible_time_save": false + } + } + ], + "general": { + "direction": "Vertical", + "background": { + "Plain": [ + 0.06, + 0.06, + 0.06, + 1 + ] + }, + "best_segment_color": [ + 1, + 0.8333333, + 0, + 1 + ], + "ahead_gaining_time_color": [ + 0, + 0.8, + 0.21333332, + 1 + ], + "ahead_losing_time_color": [ + 0.38000003, + 0.82000005, + 0.49733335, + 1 + ], + "behind_gaining_time_color": [ + 0.82000005, + 0.38000003, + 0.38000003, + 1 + ], + "behind_losing_time_color": [ + 0.8, + 0, + 0, + 1 + ], + "not_running_color": [ + 0.67, + 0.67, + 0.67, + 1 + ], + "personal_best_color": [ + 0.08000004, + 0.64733326, + 1, + 1 + ], + "paused_color": [ + 0.48, + 0.48, + 0.48, + 1 + ], + "thin_separators_color": [ + 1, + 1, + 1, + 0.09 + ], + "separators_color": [ + 1, + 1, + 1, + 0.35 + ], + "text_color": [ + 1, + 1, + 1, + 1 + ] + } +} \ No newline at end of file diff --git a/test/layouts/splits_two_rows.ls1l b/test/layouts/splits_two_rows.ls1l new file mode 100644 index 0000000..687f20a --- /dev/null +++ b/test/layouts/splits_two_rows.ls1l @@ -0,0 +1,143 @@ +{ + "components": [ + { + "Splits": { + "background": { + "Alternating": [ + [ + 0, + 0, + 0, + 0 + ], + [ + 1, + 1, + 1, + 0.04 + ] + ] + }, + "visual_split_count": 12, + "split_preview_count": 1, + "show_thin_separators": true, + "separator_last_split": true, + "always_show_last_split": true, + "fill_with_blank_space": true, + "display_two_rows": true, + "current_split_gradient": { + "Vertical": [ + [ + 0.2, + 0.4509804, + 0.95686275, + 1 + ], + [ + 0.08235294, + 0.20784314, + 0.45490196, + 1 + ] + ] + }, + "show_column_labels": false, + "columns": [ + { + "name": "Time", + "start_with": "ComparisonTime", + "update_with": "SplitTime", + "update_trigger": "OnEndingSegment", + "comparison_override": null, + "timing_method": null + }, + { + "name": "+/−", + "start_with": "Empty", + "update_with": "Delta", + "update_trigger": "Contextual", + "comparison_override": null, + "timing_method": null + } + ] + } + } + ], + "general": { + "direction": "Vertical", + "background": { + "Plain": [ + 0.06, + 0.06, + 0.06, + 1 + ] + }, + "best_segment_color": [ + 1, + 0.8333333, + 0, + 1 + ], + "ahead_gaining_time_color": [ + 0, + 0.8, + 0.21333332, + 1 + ], + "ahead_losing_time_color": [ + 0.38000003, + 0.82000005, + 0.49733335, + 1 + ], + "behind_gaining_time_color": [ + 0.82000005, + 0.38000003, + 0.38000003, + 1 + ], + "behind_losing_time_color": [ + 0.8, + 0, + 0, + 1 + ], + "not_running_color": [ + 0.67, + 0.67, + 0.67, + 1 + ], + "personal_best_color": [ + 0.08000004, + 0.64733326, + 1, + 1 + ], + "paused_color": [ + 0.48, + 0.48, + 0.48, + 1 + ], + "thin_separators_color": [ + 1, + 1, + 1, + 0.09 + ], + "separators_color": [ + 1, + 1, + 1, + 0.35 + ], + "text_color": [ + 1, + 1, + 1, + 1 + ] + } +} \ No newline at end of file diff --git a/test/layouts/splits_with_labels.ls1l b/test/layouts/splits_with_labels.ls1l new file mode 100644 index 0000000..271232a --- /dev/null +++ b/test/layouts/splits_with_labels.ls1l @@ -0,0 +1,143 @@ +{ + "components": [ + { + "Splits": { + "background": { + "Alternating": [ + [ + 0, + 0, + 0, + 0 + ], + [ + 1, + 1, + 1, + 0.04 + ] + ] + }, + "visual_split_count": 3, + "split_preview_count": 1, + "show_thin_separators": true, + "separator_last_split": true, + "always_show_last_split": true, + "fill_with_blank_space": true, + "display_two_rows": false, + "current_split_gradient": { + "Vertical": [ + [ + 0.2, + 0.4509804, + 0.95686275, + 1 + ], + [ + 0.08235294, + 0.20784314, + 0.45490196, + 1 + ] + ] + }, + "show_column_labels": true, + "columns": [ + { + "name": "Time", + "start_with": "ComparisonTime", + "update_with": "SplitTime", + "update_trigger": "OnEndingSegment", + "comparison_override": null, + "timing_method": null + }, + { + "name": "+/−", + "start_with": "Empty", + "update_with": "Delta", + "update_trigger": "Contextual", + "comparison_override": null, + "timing_method": null + } + ] + } + } + ], + "general": { + "direction": "Vertical", + "background": { + "Plain": [ + 0.06, + 0.06, + 0.06, + 1 + ] + }, + "best_segment_color": [ + 1, + 0.8333333, + 0, + 1 + ], + "ahead_gaining_time_color": [ + 0, + 0.8, + 0.21333332, + 1 + ], + "ahead_losing_time_color": [ + 0.38000003, + 0.82000005, + 0.49733335, + 1 + ], + "behind_gaining_time_color": [ + 0.82000005, + 0.38000003, + 0.38000003, + 1 + ], + "behind_losing_time_color": [ + 0.8, + 0, + 0, + 1 + ], + "not_running_color": [ + 0.67, + 0.67, + 0.67, + 1 + ], + "personal_best_color": [ + 0.08000004, + 0.64733326, + 1, + 1 + ], + "paused_color": [ + 0.48, + 0.48, + 0.48, + 1 + ], + "thin_separators_color": [ + 1, + 1, + 1, + 0.09 + ], + "separators_color": [ + 1, + 1, + 1, + 0.35 + ], + "text_color": [ + 1, + 1, + 1, + 1 + ] + } +} \ No newline at end of file diff --git a/test/layouts/title_centered_no_game_icon.ls1l b/test/layouts/title_centered_no_game_icon.ls1l new file mode 100644 index 0000000..7319aa5 --- /dev/null +++ b/test/layouts/title_centered_no_game_icon.ls1l @@ -0,0 +1,112 @@ +{ + "components": [ + { + "Title": { + "background": { + "Vertical": [ + [ + 1, + 1, + 1, + 0.13 + ], + [ + 1, + 1, + 1, + 0 + ] + ] + }, + "text_color": null, + "show_game_name": true, + "show_category_name": true, + "show_finished_runs_count": false, + "show_attempt_count": true, + "text_alignment": "Center", + "display_as_single_line": false, + "display_game_icon": false, + "show_region": false, + "show_platform": false, + "show_variables": true + } + } + ], + "general": { + "direction": "Vertical", + "background": { + "Plain": [ + 0.06, + 0.06, + 0.06, + 1 + ] + }, + "best_segment_color": [ + 1, + 0.8333333, + 0, + 1 + ], + "ahead_gaining_time_color": [ + 0, + 0.8, + 0.21333332, + 1 + ], + "ahead_losing_time_color": [ + 0.38000003, + 0.82000005, + 0.49733335, + 1 + ], + "behind_gaining_time_color": [ + 0.82000005, + 0.38000003, + 0.38000003, + 1 + ], + "behind_losing_time_color": [ + 0.8, + 0, + 0, + 1 + ], + "not_running_color": [ + 0.67, + 0.67, + 0.67, + 1 + ], + "personal_best_color": [ + 0.08000004, + 0.64733326, + 1, + 1 + ], + "paused_color": [ + 0.48, + 0.48, + 0.48, + 1 + ], + "thin_separators_color": [ + 1, + 1, + 1, + 0.09 + ], + "separators_color": [ + 1, + 1, + 1, + 0.35 + ], + "text_color": [ + 1, + 1, + 1, + 1 + ] + } +} \ No newline at end of file diff --git a/test/layouts/title_centered_with_game_icon.ls1l b/test/layouts/title_centered_with_game_icon.ls1l new file mode 100644 index 0000000..26e246e --- /dev/null +++ b/test/layouts/title_centered_with_game_icon.ls1l @@ -0,0 +1,112 @@ +{ + "components": [ + { + "Title": { + "background": { + "Vertical": [ + [ + 1, + 1, + 1, + 0.13 + ], + [ + 1, + 1, + 1, + 0 + ] + ] + }, + "text_color": null, + "show_game_name": true, + "show_category_name": true, + "show_finished_runs_count": false, + "show_attempt_count": true, + "text_alignment": "Center", + "display_as_single_line": false, + "display_game_icon": true, + "show_region": false, + "show_platform": false, + "show_variables": true + } + } + ], + "general": { + "direction": "Vertical", + "background": { + "Plain": [ + 0.06, + 0.06, + 0.06, + 1 + ] + }, + "best_segment_color": [ + 1, + 0.8333333, + 0, + 1 + ], + "ahead_gaining_time_color": [ + 0, + 0.8, + 0.21333332, + 1 + ], + "ahead_losing_time_color": [ + 0.38000003, + 0.82000005, + 0.49733335, + 1 + ], + "behind_gaining_time_color": [ + 0.82000005, + 0.38000003, + 0.38000003, + 1 + ], + "behind_losing_time_color": [ + 0.8, + 0, + 0, + 1 + ], + "not_running_color": [ + 0.67, + 0.67, + 0.67, + 1 + ], + "personal_best_color": [ + 0.08000004, + 0.64733326, + 1, + 1 + ], + "paused_color": [ + 0.48, + 0.48, + 0.48, + 1 + ], + "thin_separators_color": [ + 1, + 1, + 1, + 0.09 + ], + "separators_color": [ + 1, + 1, + 1, + 0.35 + ], + "text_color": [ + 1, + 1, + 1, + 1 + ] + } +} \ No newline at end of file diff --git a/test/layouts/title_left_no_attempt_count.ls1l b/test/layouts/title_left_no_attempt_count.ls1l new file mode 100644 index 0000000..ba031c9 --- /dev/null +++ b/test/layouts/title_left_no_attempt_count.ls1l @@ -0,0 +1,112 @@ +{ + "components": [ + { + "Title": { + "background": { + "Vertical": [ + [ + 1, + 1, + 1, + 0.13 + ], + [ + 1, + 1, + 1, + 0 + ] + ] + }, + "text_color": null, + "show_game_name": true, + "show_category_name": true, + "show_finished_runs_count": false, + "show_attempt_count": false, + "text_alignment": "Left", + "display_as_single_line": false, + "display_game_icon": false, + "show_region": false, + "show_platform": false, + "show_variables": true + } + } + ], + "general": { + "direction": "Vertical", + "background": { + "Plain": [ + 0.06, + 0.06, + 0.06, + 1 + ] + }, + "best_segment_color": [ + 1, + 0.8333333, + 0, + 1 + ], + "ahead_gaining_time_color": [ + 0, + 0.8, + 0.21333332, + 1 + ], + "ahead_losing_time_color": [ + 0.38000003, + 0.82000005, + 0.49733335, + 1 + ], + "behind_gaining_time_color": [ + 0.82000005, + 0.38000003, + 0.38000003, + 1 + ], + "behind_losing_time_color": [ + 0.8, + 0, + 0, + 1 + ], + "not_running_color": [ + 0.67, + 0.67, + 0.67, + 1 + ], + "personal_best_color": [ + 0.08000004, + 0.64733326, + 1, + 1 + ], + "paused_color": [ + 0.48, + 0.48, + 0.48, + 1 + ], + "thin_separators_color": [ + 1, + 1, + 1, + 0.09 + ], + "separators_color": [ + 1, + 1, + 1, + 0.35 + ], + "text_color": [ + 1, + 1, + 1, + 1 + ] + } +} \ No newline at end of file diff --git a/test/rendering-test.js b/test/rendering-test.js new file mode 100644 index 0000000..346789e --- /dev/null +++ b/test/rendering-test.js @@ -0,0 +1,133 @@ +const fs = require("fs"); +const path = require("path"); +const { fork } = require("child_process"); +const { + Builder, + By, + until, +} = require("selenium-webdriver"); +const chrome = require("selenium-webdriver/chrome"); +const chromedriver = require("chromedriver"); +const imghash = require("imghash"); +const hex64 = require("hex64"); +const pixelmatch = require("pixelmatch"); +const PNG = require("pngjs").PNG; + +describe("Layout Rendering Tests", () => { + let driver, serverProcess; + + const LAYOUTS_FOLDER = "test/layouts"; + const SCREENSHOTS_FOLDER = "test/screenshots"; + const SPLITS_FOLDER = "test/splits"; + + const findElement = async (selector) => { + return driver.wait(until.elementLocated(selector)); + }; + + const clickElement = async (selector) => { + const element = await driver.wait(until.elementLocated(selector)); + await element.click(); + } + + const loadFile = async (filePath) => { + const inputElement = await findElement(By.id("file-input")); + await inputElement.sendKeys(path.resolve(filePath)); + } + + before(async () => { + serverProcess = fork("./node_modules/webpack-dev-server/bin/webpack-dev-server.js"); + + const service = new chrome.ServiceBuilder(chromedriver.path).build(); + chrome.setDefaultService(service); + const options = new chrome.Options().windowSize({ width: 1200, height: 2400 }).headless(); + driver = await new Builder().forBrowser("chrome").setChromeOptions(options).build(); + + await driver.get("http://localhost:8080"); + + await driver.executeScript(() => { + HTMLInputElement.prototype.click = function() { + const existingFileInput = document.getElementById("file-input"); + if (existingFileInput) { + existingFileInput.remove(); + } + this.style.display = "none"; + this.id = "file-input"; + document.body.appendChild(this); + } + }); + + if (!fs.existsSync(SCREENSHOTS_FOLDER)) { + fs.mkdirSync(SCREENSHOTS_FOLDER); + } + }); + + const testRendering = (layoutName, splitsName, expectedHash) => { + it(`Renders the ${layoutName} layout with the ${splitsName} splits correctly`, async () => { + await clickElement(By.xpath(".//button[contains(text(), 'Layout')]")); + await clickElement(By.xpath(".//button[contains(text(), 'Import')]")); + await loadFile(`${LAYOUTS_FOLDER}/${layoutName}.ls1l`); + await clickElement(By.xpath(".//button[contains(text(), 'Back')]")); + + await clickElement(By.xpath(".//button[contains(text(), 'Splits')]")); + await clickElement(By.xpath(".//button[contains(text(), 'Import')]")); + await loadFile(`${SPLITS_FOLDER}/${splitsName}.lss`); + await clickElement(By.xpath(".//button[contains(text(), 'Back')]")); + + const layoutElement = await findElement(By.className("layout")); + const layoutScreenshot = await layoutElement.takeScreenshot(); + + const tempFilePath = `${SCREENSHOTS_FOLDER}/${layoutName}.png`; + + fs.writeFileSync(tempFilePath, layoutScreenshot, "base64"); + const actualHashHex = await imghash.hash(tempFilePath, 12); + const actualHash = hex64.encode(actualHashHex); + + const actualScreenshotPath = `${SCREENSHOTS_FOLDER}/${layoutName}_${splitsName}_${actualHash.replace("/", "$")}.png`; + const expectedScreenshotPath = `${SCREENSHOTS_FOLDER}/${layoutName}_${splitsName}_${expectedHash.replace("/", "$")}.png`; + + fs.renameSync(tempFilePath, actualScreenshotPath); + + if (actualHash !== expectedHash) { + let showWarning = false; + try { + if (fs.existsSync(expectedScreenshotPath)) { + const actualImage = PNG.sync.read(fs.readFileSync(actualScreenshotPath)); + const expectedImage = PNG.sync.read(fs.readFileSync(expectedScreenshotPath)); + const { width, height } = actualImage; + const diff = new PNG({ width, height }); + + const numPixelsDifferent = pixelmatch(actualImage.data, expectedImage.data, diff.data, width, height); + + if (numPixelsDifferent === 0) { + showWarning = true; + } + + fs.writeFileSync(`${SCREENSHOTS_FOLDER}/${layoutName}_${splitsName}_diff.png`, PNG.sync.write(diff)); + } + } + finally { + if (showWarning) { + console.warn(`Render match despite mismatching hashes! Expected hash: ${expectedHash}, actual hash: ${actualHash}`); + } else { + throw Error(`Render mismatch! Expected hash: ${expectedHash}, actual hash: ${actualHash}`) + } + } + } + }); + } + + testRendering("all_components", "default", "8AAD____-BAAAAAAAALABv_j"); + testRendering("all_components", "pmw3", "8AAD__8A-B_DuDvDLDACRP-_"); + testRendering("default", "default", "__wBAAAAAAAAAAAAAAAAAP__"); + testRendering("default", "pmw3", "_4uBiDvDODPDvDLDPDrDAP-H"); + testRendering("splits_two_rows", "celeste", "-D-D0B_DyB8D0B_D1D_jxDwD"); + testRendering("splits_with_labels", "celeste", "AKAL__8D8DkAgBsD-D6D-DOD"); + testRendering("title_centered_no_game_icon", "celeste", "__BgDw__BwAAAwDxDx__DwAA"); + testRendering("title_centered_with_game_icon", "celeste", "__AwRw__wwwAwYx5x5__x4AA"); + testRendering("title_left_no_attempt_count", "celeste", "__4A4A__4AAAMA8A8A__cAAA"); + + after(async () => { + await driver.quit(); + serverProcess.kill(); + }); +}); diff --git a/test/splits/celeste.lss b/test/splits/celeste.lss new file mode 100644 index 0000000..7749488 --- /dev/null +++ b/test/splits/celeste.lss @@ -0,0 +1 @@ +CelesteAny%PC1.2.1.500:00:00.00000003201:04:31.170000001:00:42.573000000:59:28.965000000:55:54.763000000:47:58.618000000:44:33.114000000:50:12.448000000:46:37.826000000:47:10.743000000:43:48.642000000:44:14.143000000:40:58.659000000:42:55.145000000:39:40.986000000:41:28.546000000:38:16.768000000:40:44.782000000:37:33.299000000:39:12.517000000:36:05.5790000Prologue00:00:46.769000000:00:44.404000000:00:45.237000000:00:43.6390000-Crossing00:01:20.664000000:01:06.096000000:00:31.977000000:00:20.2130000-Chasm00:01:49.624000000:01:34.009999000:00:28.960000000:00:27.9140000Forsaken City00:02:14.850000000:01:58.864000000:00:25.226000000:00:24.8540000-Intervention00:03:14.457000000:02:39.545000000:00:57.463000000:00:38.4030000-Awake00:04:30.012000000:03:52.781000000:01:13.782000000:01:10.9240000Old Site00:04:46.003000000:04:08.404000000:00:14.608000000:00:14.1780000-Huge Mess00:06:32.490000000:05:36.345000000:01:41.681000000:01:21.2430000-Elevator Shaft00:08:49.245000000:07:49.421000000:02:09.690000000:02:08.0099990-Presidential Suite00:09:50.333000000:08:48.665999000:00:56.622000000:00:55.3690000Celestial Resort00:10:59.555000000:09:54.728000000:01:02.398000000:00:59.4320000-Shrine00:12:14.659000000:10:48.703000000:01:09.932000000:00:49.0620000-Old Trial00:12:45.035000000:11:18.810000000:00:27.924000000:00:27.7100000-Cliff Face00:13:57.312000000:12:30.074000000:01:11.829000000:01:10.3120000Golden Ridge00:14:59.560000000:13:30.084000000:01:01.224000000:00:58.5480000-Depths00:15:55.469000000:14:06.396000000:00:55.909000000:00:36.3120000-Unravelling00:17:12.483000000:15:22.709000000:01:16.131000000:01:14.9700000-Search00:18:23.249000000:16:31.525000000:01:10.766000000:01:08.8160000-Rescue00:19:18.915000000:17:25.500000000:00:49.846000000:00:49.0620000Mirror Temple00:21:07.225000000:19:11.937000000:01:30.570000000:01:29.1480000-Lake00:21:46.404000000:19:32.609000000:00:39.179000000:00:20.6720000-Hollows00:22:25.601000000:20:10.451000000:00:39.197000000:00:37.8420000-Reflection00:24:24.105000000:22:05.218000000:01:54.336000000:01:51.0270000-Rock Bottom00:25:12.998000000:22:52.495000000:00:48.893000000:00:47.2770000-Resolution00:28:04.506000000:25:36.443000000:02:51.508000000:02:43.9480000Reflection00:28:28.494000000:26:00.226000000:00:21.310000000:00:21.1820000-500M00:29:34.947000000:26:49.713000000:01:01.628000000:00:45.2710000-1000M00:30:30.753000000:27:43.875000000:00:55.806000000:00:54.1620000-1500M00:31:27.444000000:28:36.303000000:00:56.691000000:00:52.4280000-2000M00:32:38.059000000:29:44.303000000:01:10.615000000:01:08.0000000-2500M00:34:15.286999000:31:18.279000000:01:37.228000000:01:33.9760000-3000M00:35:40.926000000:32:40.661000000:01:25.639000000:01:22.3820000The Summit00:39:12.517000000:36:05.579000000:03:31.591000000:03:24.9180000PrologueChapter1Checkpoint1Chapter1Checkpoint2Chapter1Chapter2Checkpoint1Chapter2Checkpoint2Chapter2Chapter3Checkpoint1Chapter3Checkpoint2Chapter3Checkpoint3Chapter3Chapter4Checkpoint1Chapter4Checkpoint2Chapter4Checkpoint3Chapter4Chapter5Checkpoint1Chapter5Checkpoint2Chapter5Checkpoint3Chapter5Checkpoint4Chapter5Chapter6Checkpoint1Chapter6Checkpoint2Chapter6Checkpoint3Chapter6Checkpoint4Chapter6Checkpoint5Chapter6Chapter7Checkpoint1Chapter7Checkpoint2Chapter7Checkpoint3Chapter7Checkpoint4Chapter7Checkpoint5Chapter7Checkpoint6Chapter7Epilogue \ No newline at end of file diff --git a/test/splits/default.lss b/test/splits/default.lss new file mode 100644 index 0000000..2dff81a --- /dev/null +++ b/test/splits/default.lss @@ -0,0 +1 @@ +GameCategory00:00:00.00000000Time \ No newline at end of file diff --git a/test/splits/pmw3.lss b/test/splits/pmw3.lss new file mode 100644 index 0000000..1523fd1 --- /dev/null +++ b/test/splits/pmw3.lss @@ -0,0 +1 @@ +Pac-Man World 3Any%PCUSA / NTSCEasyConsole/PC00:00:00.000000027002:31:48.750000002:14:45.469000002:03:12.442000002:01:46.219000001:56:59.463000001:54:35.416000001:53:00.292000001:51:31.969000001:49:45.527000001:47:07.064000001:46:34.242000001:45:48.406000001:45:12.156000001:45:04.803000001:44:28.952000001:43:29.314000001:42:55.224000001:45:20.238000001:44:45.611000001:39:54.092000001:39:29.106000001:38:09.506000001:37:37.452000001:41:36.143000001:41:00.570000001:43:23.296000001:42:40.970000001:35:29.150000001:35:00.043000001:34:54.273000001:34:22.109000001:34:20.966000001:33:54.962000001:34:44.555000001:34:12.337000001:34:13.526000001:33:42.968000001:34:05.269000001:33:36.712000001:32:24.213000001:31:58.061000001:34:52.158000001:34:18.401000001:38:04.451000001:37:25.418000001:35:30.995000001:34:45.432000001:31:20.925000001:30:46.918000001:29:47.059000001:29:13.170000001:29:20.978000001:28:50.672000001:30:27.544000001:29:50.350000001:29:24.791000001:28:51.061000001:29:55.958000001:29:19.603000001:30:07.321000001:29:32.766000001:29:22.271000001:28:55.219000001:28:33.720000001:28:06.441000001:34:54.658000001:34:12.620000001:33:13.440000001:32:23.871000001:33:36.570000001:32:51.576000001:32:13.766000001:31:39.558000001:32:26.898000001:31:47.983000001:33:12.723000001:32:24.265000001:29:34.189000001:28:52.675000001:28:21.506000001:27:47.488000001:26:46.925000001:26:08.172000001:26:33.933000001:25:55.233000001:23:34.585000001:23:00.2630000Bot Boneyard00:01:57.969000000:01:55.818000000:01:54.505000000:01:52.5410000Banni Wastelands00:06:26.113000000:06:23.026000000:04:11.169000000:04:10.2890000The Spectral Cliffs00:12:55.180000000:12:49.276000000:06:29.067000000:06:26.2500000Gogekka Central00:19:25.296000000:19:17.310000000:06:30.116000000:06:28.0340000The Spectral Vale00:25:49.512000000:25:39.429000000:05:47.618000000:05:46.5240000Zephyr Heights00:33:59.265000000:33:44.124000000:07:51.283000000:07:46.2090000Ancient Catacombs00:38:37.463000000:38:20.200000000:04:07.738000000:04:06.7680000Gogekka Heights00:45:40.276000000:45:20.902000000:06:28.814000000:06:27.8250000Banni Canyon00:52:04.069000000:51:42.654000000:06:23.793000000:06:21.7520000Toc-Man Battle00:54:50.445000000:54:28.166000000:02:46.287000000:02:45.4189990Cragstone Bridge00:59:08.122000000:58:44.759000000:04:17.677000000:04:16.5930000Erwin's Fortress01:06:40.317000001:06:14.793000000:07:32.195000000:07:30.0340000Dungen Gunden01:13:16.366000001:12:45.737000000:06:36.049000000:06:30.9440000The Spectral Zenith01:20:31.371000001:19:58.646000000:07:12.519000000:07:10.2650000Shadow Temple01:23:34.585000001:23:00.263000000:03:03.214000000:03:01.61700001.5C:\Users\Sergey\Downloads\LiveSplit_1.7.5\Components\LiveSplit.PMW3.aslTrueTrueTrueFalse \ No newline at end of file