scriptorium 0.0.3 → 0.7.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.lt3 +324 -0
- data/README.md +3155 -1
- data/assets/.DS_Store +0 -0
- data/assets/README.md +44 -0
- data/assets/icons/social/reddit.png +0 -0
- data/assets/icons/social/x-logo.png +0 -0
- data/assets/icons/ui/.DS_Store +0 -0
- data/assets/icons/ui/back.png +0 -0
- data/assets/icons/ui/copy.png +0 -0
- data/assets/icons/ui/down.png +0 -0
- data/assets/icons/ui/end.png +0 -0
- data/assets/icons/ui/exit.png +0 -0
- data/assets/icons/ui/foo +10 -0
- data/assets/icons/ui/home.png +0 -0
- data/assets/icons/ui/left.png +0 -0
- data/assets/icons/ui/next.png +0 -0
- data/assets/icons/ui/right.png +0 -0
- data/assets/icons/ui/start.png +0 -0
- data/assets/icons/ui/up.png +0 -0
- data/assets/imagenotfound.jpg +0 -0
- data/assets/samples/placeholder.svg +9 -0
- data/assets/themes/standard/favicon.svg +6 -0
- data/bin/sblog +84 -5
- data/bin/scriptorium +1 -0
- data/doc/README.txt +6 -0
- data/doc/anti-amnesia/20250727-054000-scriptorium-overview.md +94 -0
- data/doc/anti-amnesia/20250727-123000-anti-amnesia-conventions.md +2 -0
- data/doc/anti-amnesia/20250727-172600-cursor-rbenv-ruby-version-mystery.md +45 -0
- data/doc/anti-amnesia/20250727-172900-ai-cognitive-assessment-capabilities.md +40 -0
- data/doc/anti-amnesia/20250728-124243-aaa-syntax-clarification.md +46 -0
- data/doc/anti-amnesia/20250729-210000-reddit-autopost-integration-complete.md +158 -0
- data/doc/anti-amnesia/20250804-190500-cognitive-loop-bug.md +35 -0
- data/doc/anti-amnesia/20250804-190700-anti-amnesia-timestamping-fix.md +27 -0
- data/doc/anti-amnesia/20250807-213025.md +116 -0
- data/doc/anti-amnesia/20250901-211714-codemirror-integration-and-web-tests.md +172 -0
- data/doc/anti-amnesia/20250902-002402-backup-restore-system.md +126 -0
- data/doc/anti-amnesia/20250907-203339-backup-metadata-implementation.md +66 -0
- data/doc/banner_svg_config.md +114 -0
- data/doc/contrib.lt3 +8 -0
- data/doc/dependencies.md +281 -0
- data/doc/hacker.lt3 +5 -0
- data/doc/imported/0001-elixir-conf-2014/metadata.txt +7 -0
- data/doc/imported/0001-elixir-conf-2014/post.html +37 -0
- data/doc/imported/0001-elixir-conf-2014/source.lt3 +22 -0
- data/doc/imported/0002-programmers-and-word-processing/metadata.txt +7 -0
- data/doc/imported/0002-programmers-and-word-processing/post.html +192 -0
- data/doc/imported/0002-programmers-and-word-processing/source.lt3 +146 -0
- data/doc/imported/0003-how-to-turn-your-brain-sideways/metadata.txt +7 -0
- data/doc/imported/0003-how-to-turn-your-brain-sideways/post.html +60 -0
- data/doc/imported/0003-how-to-turn-your-brain-sideways/source.lt3 +40 -0
- data/doc/imported/0004-upcoming-lone-star-ruby-conference/metadata.txt +7 -0
- data/doc/imported/0004-upcoming-lone-star-ruby-conference/post.html +42 -0
- data/doc/imported/0004-upcoming-lone-star-ruby-conference/source.lt3 +24 -0
- data/doc/imported/0005-elixir-conf-2015-announced/metadata.txt +7 -0
- data/doc/imported/0005-elixir-conf-2015-announced/post.html +30 -0
- data/doc/imported/0005-elixir-conf-2015-announced/source.lt3 +16 -0
- data/doc/imported/0006-ruby-for-dinosaurs/metadata.txt +7 -0
- data/doc/imported/0006-ruby-for-dinosaurs/post.html +43 -0
- data/doc/imported/0006-ruby-for-dinosaurs/source.lt3 +27 -0
- data/doc/imported/0007-phoenix-isnt-rails/metadata.txt +7 -0
- data/doc/imported/0007-phoenix-isnt-rails/post.html +116 -0
- data/doc/imported/0007-phoenix-isnt-rails/source.lt3 +87 -0
- data/doc/imported/0008-concerning-the-term-monkeypatching/metadata.txt +7 -0
- data/doc/imported/0008-concerning-the-term-monkeypatching/post.html +129 -0
- data/doc/imported/0008-concerning-the-term-monkeypatching/source.lt3 +92 -0
- data/doc/imported/0009-announcement-coming-soon/metadata.txt +7 -0
- data/doc/imported/0009-announcement-coming-soon/post.html +33 -0
- data/doc/imported/0009-announcement-coming-soon/source.lt3 +19 -0
- data/doc/imported/0010-immutable-data-ditching-the-wax-tablet/metadata.txt +7 -0
- data/doc/imported/0010-immutable-data-ditching-the-wax-tablet/post.html +175 -0
- data/doc/imported/0010-immutable-data-ditching-the-wax-tablet/source.lt3 +139 -0
- data/doc/imported/0011-computer-science-as-a-lost-art/metadata.txt +7 -0
- data/doc/imported/0011-computer-science-as-a-lost-art/post.html +139 -0
- data/doc/imported/0011-computer-science-as-a-lost-art/source.lt3 +104 -0
- data/doc/imported/0012-ruby-day-in-turin-italy/metadata.txt +7 -0
- data/doc/imported/0012-ruby-day-in-turin-italy/post.html +42 -0
- data/doc/imported/0012-ruby-day-in-turin-italy/source.lt3 +24 -0
- data/doc/imported/0013-rubyday-was-a-success/metadata.txt +7 -0
- data/doc/imported/0013-rubyday-was-a-success/post.html +44 -0
- data/doc/imported/0013-rubyday-was-a-success/source.lt3 +27 -0
- data/doc/imported/0014-working-on-the-blogging-software/metadata.txt +7 -0
- data/doc/imported/0014-working-on-the-blogging-software/post.html +63 -0
- data/doc/imported/0014-working-on-the-blogging-software/source.lt3 +41 -0
- data/doc/imported/0015-ok-its-not-really-a-lost-art/metadata.txt +7 -0
- data/doc/imported/0015-ok-its-not-really-a-lost-art/post.html +172 -0
- data/doc/imported/0015-ok-its-not-really-a-lost-art/source.lt3 +134 -0
- data/doc/imported/0016-an-in-operator-for-ruby/metadata.txt +7 -0
- data/doc/imported/0016-an-in-operator-for-ruby/post.html +155 -0
- data/doc/imported/0016-an-in-operator-for-ruby/source.lt3 +106 -0
- data/doc/imported/0017-the-forgotten-mathematician/metadata.txt +7 -0
- data/doc/imported/0017-the-forgotten-mathematician/post.html +161 -0
- data/doc/imported/0017-the-forgotten-mathematician/source.lt3 +119 -0
- data/doc/imported/0018-ruby-puns/metadata.txt +7 -0
- data/doc/imported/0018-ruby-puns/post.html +46 -0
- data/doc/imported/0018-ruby-puns/source.lt3 +28 -0
- data/doc/imported/0019-custom-exceptions-via-metaprogramming/metadata.txt +7 -0
- data/doc/imported/0019-custom-exceptions-via-metaprogramming/post.html +138 -0
- data/doc/imported/0019-custom-exceptions-via-metaprogramming/source.lt3 +101 -0
- data/doc/imported/0020-fffff/metadata.txt +7 -0
- data/doc/imported/0020-fffff/post.html +24 -0
- data/doc/imported/0020-fffff/source.lt3 +12 -0
- data/doc/imported/0021-trying-ror-yet-again/metadata.txt +7 -0
- data/doc/imported/0021-trying-ror-yet-again/post.html +26 -0
- data/doc/imported/0021-trying-ror-yet-again/source.lt3 +12 -0
- data/doc/imported/0023-doctor-sleep/metadata.txt +7 -0
- data/doc/imported/0023-doctor-sleep/post.html +63 -0
- data/doc/imported/0023-doctor-sleep/source.lt3 +44 -0
- data/doc/imported/0024-just-a-test/metadata.txt +7 -0
- data/doc/imported/0024-just-a-test/post.html +24 -0
- data/doc/imported/0024-just-a-test/source.lt3 +12 -0
- data/doc/imported/import_summary.txt +98 -0
- data/doc/livetext-informal-spec.txt +65 -0
- data/doc/myuserdoc/ch-0.lt3 +31 -0
- data/doc/myuserdoc/ch-1.lt3 +37 -0
- data/doc/myuserdoc/ch-10.lt3 +22 -0
- data/doc/myuserdoc/ch-2.lt3 +37 -0
- data/doc/myuserdoc/ch-3.lt3 +19 -0
- data/doc/myuserdoc/ch-4.lt3 +43 -0
- data/doc/myuserdoc/ch-5.lt3 +22 -0
- data/doc/myuserdoc/ch-6.lt3 +19 -0
- data/doc/myuserdoc/ch-7.lt3 +16 -0
- data/doc/myuserdoc/ch-8.lt3 +13 -0
- data/doc/myuserdoc/ch-9.lt3 +19 -0
- data/doc/myuserdoc/tweak.rb +18 -0
- data/doc/myuserdoc/userdoc-toc.txt +88 -0
- data/doc/old-posts/0001-elixir-conf-2014.lt3 +24 -0
- data/doc/old-posts/0002-programmers-and-word-processing.lt3 +150 -0
- data/doc/old-posts/0003-how-to-turn-your-brain-sideways.lt3 +43 -0
- data/doc/old-posts/0004-upcoming-lone-star-ruby-conference.lt3 +26 -0
- data/doc/old-posts/0005-elixir-conf-2015-announced.lt3 +17 -0
- data/doc/old-posts/0006-ruby-for-dinosaurs.lt3 +30 -0
- data/doc/old-posts/0007-phoenix-isnt-rails.lt3 +90 -0
- data/doc/old-posts/0008-concerning-the-term-monkeypatching.lt3 +105 -0
- data/doc/old-posts/0009-announcement-coming-soon.lt3 +20 -0
- data/doc/old-posts/0010-immutable-data-ditching-the-wax-tablet.lt3 +142 -0
- data/doc/old-posts/0011-computer-science-as-a-lost-art.lt3 +117 -0
- data/doc/old-posts/0012-ruby-day-in-turin-italy.lt3 +26 -0
- data/doc/old-posts/0013-rubyday-was-a-success.lt3 +28 -0
- data/doc/old-posts/0014-working-on-the-blogging-software.lt3 +42 -0
- data/doc/old-posts/0015-ok-its-not-really-a-lost-art.lt3 +137 -0
- data/doc/old-posts/0016-an-in-operator-for-ruby.lt3 +142 -0
- data/doc/old-posts/0017-the-forgotten-mathematician.lt3 +129 -0
- data/doc/old-posts/0018-ruby-puns.lt3 +31 -0
- data/doc/old-posts/0019-custom-exceptions-via-metaprogramming.lt3 +116 -0
- data/doc/old-posts/0021-trying-ror-yet-again.lt3 +35 -0
- data/doc/old-posts/0023-doctor-sleep.lt3 +43 -0
- data/doc/old-posts/0024-just-a-test.lt3 +12 -0
- data/doc/old-posts/0025-trying-another-post.lt3 +12 -0
- data/doc/old-repo +1 -0
- data/doc/reddit_credentials_template.json +8 -0
- data/doc/reddit_integration.md +207 -0
- data/doc/user.lt3 +35 -0
- data/doc/user_guide_section_1.md +137 -0
- data/doc/user_guide_section_10.md +515 -0
- data/doc/user_guide_section_11.md +708 -0
- data/doc/user_guide_section_2.md +233 -0
- data/doc/user_guide_section_3.md +5 -0
- data/doc/user_guide_section_4.md +221 -0
- data/doc/user_guide_section_5.md +243 -0
- data/doc/user_guide_section_6.md +147 -0
- data/doc/user_guide_section_7.md +311 -0
- data/doc/user_guide_section_8.md +224 -0
- data/doc/user_guide_section_9.md +375 -0
- data/lib/rouge/lexers/livetext.rb +74 -0
- data/lib/scriptorium/api.rb +2373 -0
- data/lib/scriptorium/banner_svg.rb +729 -0
- data/lib/scriptorium/contract.rb +34 -0
- data/lib/scriptorium/exceptions.rb +201 -1
- data/lib/scriptorium/helpers.rb +675 -0
- data/lib/scriptorium/post.rb +259 -0
- data/lib/scriptorium/reddit.rb +83 -0
- data/lib/scriptorium/repo.rb +938 -0
- data/lib/scriptorium/standard_files.rb +149 -0
- data/lib/scriptorium/support/bootstrap/css.txt +5 -0
- data/lib/scriptorium/support/bootstrap/js.txt +4 -0
- data/lib/scriptorium/support/common_js/clipboard.js +35 -0
- data/lib/scriptorium/support/common_js/content-loader.js +187 -0
- data/lib/scriptorium/support/common_js/navigation.js +52 -0
- data/lib/scriptorium/support/common_js/syntax-highlighting.js +27 -0
- data/lib/scriptorium/support/config/reddit.txt +10 -0
- data/lib/scriptorium/support/config/reddit_template.txt +17 -0
- data/lib/scriptorium/support/config/social.txt +8 -0
- data/lib/scriptorium/support/highlight/css.txt +2 -0
- data/lib/scriptorium/support/highlight/custom.css +119 -0
- data/lib/scriptorium/support/highlight/js.txt +1 -0
- data/lib/scriptorium/support/post_index/config.txt +15 -0
- data/lib/scriptorium/support/post_index/style.css +55 -0
- data/lib/scriptorium/support/templates/index_entry.lt3 +16 -0
- data/lib/scriptorium/support/templates/initial_post.lt3 +12 -0
- data/lib/scriptorium/support/templates/layout.txt +5 -0
- data/lib/scriptorium/support/templates/post.lt3 +104 -0
- data/lib/scriptorium/support/theme/footer.lt3 +2 -0
- data/lib/scriptorium/support/theme/header.lt3 +4 -0
- data/lib/scriptorium/support/theme/left.lt3 +3 -0
- data/lib/scriptorium/support/theme/main.lt3 +5 -0
- data/lib/scriptorium/support/theme/right.lt3 +3 -0
- data/lib/scriptorium/theme.rb +192 -0
- data/lib/scriptorium/version.rb +1 -1
- data/lib/scriptorium/view.rb +1021 -0
- data/lib/scriptorium/widgets/featured_posts.rb +149 -0
- data/lib/scriptorium/widgets/links.rb +112 -0
- data/lib/scriptorium/widgets/pages.rb +133 -0
- data/lib/scriptorium/widgets/widget.rb +133 -0
- data/lib/scriptorium.rb +38 -34
- data/lib/skeleton.rb +10 -1
- data/scriptorium.gemspec +17 -5
- data/test/README.md +69 -0
- data/test/WEB_INTEGRATION_README.md +196 -0
- data/test/all +83 -0
- data/test/api_demo.rb +99 -0
- data/test/assets/imagenotfound.jpg +0 -0
- data/test/assets/images/.DS_Store +0 -0
- data/test/assets/images/README.md +27 -0
- data/test/assets/images/odd_aspect.png +0 -0
- data/test/assets/images/perfect.png +0 -0
- data/test/assets/images/small.png +0 -0
- data/test/assets/images/tall.png +0 -0
- data/test/assets/images/very_tall.png +0 -0
- data/test/assets/images/very_wide.png +0 -0
- data/test/assets/images/wide.png +0 -0
- data/test/assets/testbanner.jpg +0 -0
- data/test/banner_svg/simple_helpers.rb +13 -0
- data/test/banner_svg/unit.rb +1000 -0
- data/test/config/deployment.txt +5 -0
- data/test/ed_test.rb +204 -0
- data/test/integration/cursor_banner_combinations.rb +193 -0
- data/test/integration/cursor_banner_features.rb +374 -0
- data/test/integration/integration_test.rb +326 -0
- data/test/integration/preview_flow_test.rb +94 -0
- data/test/livetext_plugin_test.rb +500 -0
- data/test/manual/asset_mgmt.rb +67 -0
- data/test/manual/banner-tests/index.html +45 -0
- data/test/manual/banner-tests/svg.txt +3 -0
- data/test/manual/banner-tests/test01.html +122 -0
- data/test/manual/banner-tests/test02.html +122 -0
- data/test/manual/banner-tests/test03.html +122 -0
- data/test/manual/banner-tests/test04.html +129 -0
- data/test/manual/banner-tests/test05.html +129 -0
- data/test/manual/banner-tests/test06.html +129 -0
- data/test/manual/banner-tests/test07.html +129 -0
- data/test/manual/banner-tests/test08.html +123 -0
- data/test/manual/banner-tests/test09.html +123 -0
- data/test/manual/banner-tests/test10.html +123 -0
- data/test/manual/banner-tests/test11.html +123 -0
- data/test/manual/banner-tests/test12.html +123 -0
- data/test/manual/banner-tests/test13.html +123 -0
- data/test/manual/banner-tests/test14.html +123 -0
- data/test/manual/banner-tests/test15.html +122 -0
- data/test/manual/banner-tests/test16.html +122 -0
- data/test/manual/banner-tests/test17.html +122 -0
- data/test/manual/banner-tests/test18.html +132 -0
- data/test/manual/banner-tests/test19.html +132 -0
- data/test/manual/banner-tests/test20.html +132 -0
- data/test/manual/banner-tests/test21.html +132 -0
- data/test/manual/banner-tests/test22.html +132 -0
- data/test/manual/banner-tests/test23.html +132 -0
- data/test/manual/banner-tests/test24.html +132 -0
- data/test/manual/banner-tests/test25.html +131 -0
- data/test/manual/banner_environment.rb +205 -0
- data/test/manual/codemirror_demo.html +773 -0
- data/test/manual/create_posts_for_web.rb +114 -0
- data/test/manual/environment.rb +67 -0
- data/test/manual/make_banner.rb +153 -0
- data/test/manual/preview_manual_test.rb +129 -0
- data/test/manual/sample_banner_config.txt +12 -0
- data/test/manual/test_advanced_widgets.rb +73 -0
- data/test/manual/test_banner_combinations.rb +120 -0
- data/test/manual/test_banner_features.rb +306 -0
- data/test/manual/test_banner_integration.rb +115 -0
- data/test/manual/test_banner_radial.rb +87 -0
- data/test/manual/test_basic_posts.rb +47 -0
- data/test/manual/test_layout_widgets.rb +40 -0
- data/test/manual/test_pagination.rb +24 -0
- data/test/manual/test_random_posts.rb +38 -0
- data/test/manual/test_syntax_highlighting.rb +167 -0
- data/test/rubytext/rubytext_comprehensive_test.rb +307 -0
- data/test/rubytext/rubytext_demo_test.rb +42 -0
- data/test/rubytext/rubytext_testing_guide.md +277 -0
- data/test/run_automated_tests.rb +45 -0
- data/test/staging/.DS_Store +0 -0
- data/test/support/preview_utils.rb +88 -0
- data/test/syntax_highlighting_test.lt3 +124 -0
- data/test/test_gem_assets.rb +48 -0
- data/test/test_helpers.rb +240 -0
- data/test/tui_editor_integration_test.rb +296 -0
- data/test/tui_integration_test.rb +883 -0
- data/test/unit/api.rb +1776 -0
- data/test/unit/asset_management.rb +219 -0
- data/test/unit/backup_test.rb +451 -0
- data/test/unit/clipboard_test.rb +60 -0
- data/test/unit/contract_test.rb +69 -0
- data/test/unit/core.rb +1211 -0
- data/test/unit/deploy_config_test.rb +248 -0
- data/test/unit/deploy_test.rb +478 -0
- data/test/unit/edit_post_test.rb +168 -0
- data/test/unit/gem_asset_management.rb +183 -0
- data/test/unit/livetext_basic.rb +57 -0
- data/test/unit/livetext_compatibility.rb +82 -0
- data/test/unit/parse_cmd_test.rb +260 -0
- data/test/unit/permalink_copy_test.rb +211 -0
- data/test/unit/post.rb +309 -0
- data/test/unit/post_index_config_test.rb +258 -0
- data/test/unit/post_state_helpers_test.rb +137 -0
- data/test/unit/read_commented_file_test.rb +278 -0
- data/test/unit/reddit_test.rb +235 -0
- data/test/unit/repo.rb +569 -0
- data/test/unit/social_test.rb +366 -0
- data/test/unit/syntax_highlighting.rb +70 -0
- data/test/unit/theme_management_test.rb +91 -0
- data/test/unit/view.rb +498 -0
- data/test/unit/widgets.rb +669 -0
- data/test/web_integration_test.rb +231 -0
- data/test/web_test_helper.rb +218 -0
- data/test/web_workflow_test.rb +527 -0
- data/test/wizard_test.rb +123 -0
- data/ui/README.md +67 -0
- data/ui/common/lib/ui_common.rb +8 -0
- data/ui/rubytext/README.md +191 -0
- data/ui/rubytext/bin/scriptorium-rubytext +402 -0
- data/ui/rubytext/lib/rubytext_ui.rb +300 -0
- data/ui/tui/bin/scriptorium +1890 -0
- data/ui/tui/test/tui_test.rb +23 -0
- data/ui/web/app/app.rb +2600 -0
- data/ui/web/app/assets/livetext_mode.js +244 -0
- data/ui/web/app/error_helpers.rb +150 -0
- data/ui/web/app/views/advanced_config.erb +196 -0
- data/ui/web/app/views/asset_management.erb +645 -0
- data/ui/web/app/views/backup_management.erb +238 -0
- data/ui/web/app/views/banner_config.erb +200 -0
- data/ui/web/app/views/config_widget.erb +232 -0
- data/ui/web/app/views/configure_view.erb +401 -0
- data/ui/web/app/views/dashboard.erb +154 -0
- data/ui/web/app/views/deploy_config.erb +149 -0
- data/ui/web/app/views/edit_pages.erb +363 -0
- data/ui/web/app/views/edit_post.erb +175 -0
- data/ui/web/app/views/edit_theme.erb +73 -0
- data/ui/web/app/views/edit_theme_file.erb +74 -0
- data/ui/web/app/views/error_page.erb +29 -0
- data/ui/web/app/views/header_config.erb +155 -0
- data/ui/web/app/views/layout_config.erb +147 -0
- data/ui/web/app/views/navbar_config.erb +411 -0
- data/ui/web/app/views/theme_management.erb +130 -0
- data/ui/web/app/views/view_dashboard.erb +779 -0
- data/ui/web/app/views/widgets.erb +249 -0
- data/ui/web/bin/scriptorium-web +164 -0
- data/ui/web/test/web_basic_test.rb +38 -0
- data/ui/web/test_navbar.txt +7 -0
- data/ui/web/tmp/timing.log +17 -0
- data/ui/web/tmp/web_server.log +0 -0
- metadata +434 -8
- data/lib/scriptorium/engine.rb +0 -22
- data/test/engine/unit.rb +0 -44
@@ -0,0 +1,231 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'minitest/autorun'
|
4
|
+
require_relative '../lib/scriptorium'
|
5
|
+
require_relative 'web_test_helper'
|
6
|
+
|
7
|
+
class WebIntegrationTest < Minitest::Test
|
8
|
+
include Scriptorium::Helpers
|
9
|
+
include WebTestHelper
|
10
|
+
|
11
|
+
# Test repository path and web server config are now in WebTestHelper
|
12
|
+
|
13
|
+
def setup
|
14
|
+
cleanup_test_repo
|
15
|
+
# Don't create repo here - let the web app create it interactively
|
16
|
+
# Disable DBC contracts in tests
|
17
|
+
ENV['DBC_DISABLED'] = 'true'
|
18
|
+
|
19
|
+
# rbenv hack to ensure correct Ruby version
|
20
|
+
ENV['PATH'] = "#{ENV['HOME']}/.rbenv/shims:#{ENV['PATH']}"
|
21
|
+
ENV['RBENV_VERSION'] = '3.2.3'
|
22
|
+
end
|
23
|
+
|
24
|
+
def teardown
|
25
|
+
cleanup_test_repo
|
26
|
+
stop_web_server
|
27
|
+
end
|
28
|
+
|
29
|
+
# Test basic web app functionality
|
30
|
+
def test_001_basic_web_interaction
|
31
|
+
start_web_server
|
32
|
+
|
33
|
+
# Test that web app starts and responds
|
34
|
+
response = get("/status")
|
35
|
+
assert_response_success(response, "Status endpoint should work")
|
36
|
+
|
37
|
+
# Verify test mode is working
|
38
|
+
data = parse_json_response(response)
|
39
|
+
assert data, "Should have status data"
|
40
|
+
assert_nil data["current_view"], "Should not have current view (test repo empty)"
|
41
|
+
assert_equal false, data["repo_loaded"], "Should not have repo loaded (test repo empty)"
|
42
|
+
|
43
|
+
# Basic web interaction working
|
44
|
+
end
|
45
|
+
|
46
|
+
# Test view creation workflow via web
|
47
|
+
def test_002_view_creation_workflow
|
48
|
+
start_web_server
|
49
|
+
|
50
|
+
# Test view creation form
|
51
|
+
response = get("/")
|
52
|
+
assert_response_success(response, "Dashboard should load")
|
53
|
+
assert_includes_concise response, "Create Repository", "Should show create repository option"
|
54
|
+
|
55
|
+
# Test repository creation (this would be a POST request in real usage)
|
56
|
+
# For now, we'll test that the form elements exist
|
57
|
+
assert_includes_concise response, "create_repo", "Should have repository creation form"
|
58
|
+
|
59
|
+
# View creation workflow accessible
|
60
|
+
end
|
61
|
+
|
62
|
+
# Test asset management via web
|
63
|
+
def test_003_asset_management_web
|
64
|
+
start_web_server
|
65
|
+
|
66
|
+
# Setup test environment first
|
67
|
+
setup_test_environment
|
68
|
+
|
69
|
+
# Test asset management page
|
70
|
+
response = get("/asset_management")
|
71
|
+
assert_response_success(response, "Asset management page should load")
|
72
|
+
assert_includes_concise response, "Asset Management", "Should show asset management interface"
|
73
|
+
|
74
|
+
# Asset management accessible
|
75
|
+
end
|
76
|
+
|
77
|
+
# Test view configuration via web
|
78
|
+
def test_004_view_configuration_web
|
79
|
+
start_web_server
|
80
|
+
|
81
|
+
# Setup test environment first
|
82
|
+
setup_test_environment
|
83
|
+
|
84
|
+
# Test view configuration page
|
85
|
+
response = get("/advanced_config")
|
86
|
+
assert_response_success(response, "Advanced config page should load")
|
87
|
+
assert_includes_concise response, "Advanced Configuration", "Should show configuration interface"
|
88
|
+
|
89
|
+
# View configuration accessible
|
90
|
+
end
|
91
|
+
|
92
|
+
# Test deployment configuration via web
|
93
|
+
def test_005_deployment_configuration_web
|
94
|
+
start_web_server
|
95
|
+
|
96
|
+
# Setup test environment first
|
97
|
+
setup_test_environment
|
98
|
+
|
99
|
+
# Test deployment configuration page
|
100
|
+
response = get("/deploy_config")
|
101
|
+
assert_response_success(response, "Deploy config page should load")
|
102
|
+
assert_includes_concise response, "Deployment Configuration", "Should show deployment interface"
|
103
|
+
|
104
|
+
# Deployment configuration accessible
|
105
|
+
end
|
106
|
+
|
107
|
+
# Test view generation via web
|
108
|
+
def test_006_view_generation_web
|
109
|
+
start_web_server
|
110
|
+
|
111
|
+
# Setup test environment first
|
112
|
+
setup_test_environment
|
113
|
+
|
114
|
+
# Test view generation
|
115
|
+
response = post("/generate_view", { 'view_name' => 'test-view' })
|
116
|
+
assert_response_success(response, "View generation should succeed")
|
117
|
+
|
118
|
+
# Check that the generated HTML has valid JavaScript
|
119
|
+
index_file = "ui/web/scriptorium-TEST/views/test-view/output/index.html"
|
120
|
+
assert File.exist?(index_file), "Index file should exist after generation"
|
121
|
+
|
122
|
+
html_content = File.read(index_file)
|
123
|
+
|
124
|
+
# Check that load_main function is defined
|
125
|
+
assert_match /function load_main/, html_content, "load_main function should be defined"
|
126
|
+
|
127
|
+
# Check that the SVG script loads properly (functional test)
|
128
|
+
assert_match /console\.log\('SVG script loaded'\)/, html_content,
|
129
|
+
"Should have SVG script loaded message"
|
130
|
+
end
|
131
|
+
|
132
|
+
# Test generated HTML has clickable posts
|
133
|
+
def test_007_generated_html_has_clickable_posts
|
134
|
+
start_web_server
|
135
|
+
|
136
|
+
# Setup test environment first
|
137
|
+
setup_test_environment
|
138
|
+
|
139
|
+
# Create a test post
|
140
|
+
post("/create_post", {
|
141
|
+
title: "Test Post",
|
142
|
+
body: "This is a test post body",
|
143
|
+
views: "test-view",
|
144
|
+
blurb: "Test post blurb"
|
145
|
+
})
|
146
|
+
|
147
|
+
# Generate the view first
|
148
|
+
post("/generate_view", { 'view_name' => 'test-view' })
|
149
|
+
|
150
|
+
# Check the generated HTML
|
151
|
+
index_file = "ui/web/scriptorium-TEST/views/test-view/output/index.html"
|
152
|
+
html_content = File.read(index_file)
|
153
|
+
|
154
|
+
# Should have onclick handlers for posts
|
155
|
+
assert_match /onclick="load_main\('index\.html\?post=/, html_content,
|
156
|
+
"Should have onclick handlers for posts"
|
157
|
+
|
158
|
+
# Should have post files
|
159
|
+
posts_dir = "ui/web/scriptorium-TEST/views/test-view/output/posts"
|
160
|
+
assert Dir.exist?(posts_dir), "Posts directory should exist"
|
161
|
+
|
162
|
+
post_files = Dir.glob("#{posts_dir}/*.html")
|
163
|
+
assert post_files.length > 0, "Should have generated post files"
|
164
|
+
end
|
165
|
+
|
166
|
+
def test_008_collapsible_create_post_form
|
167
|
+
start_web_server
|
168
|
+
setup_test_environment
|
169
|
+
|
170
|
+
# Get the view dashboard
|
171
|
+
response = get("/view/test-view")
|
172
|
+
assert_response_success(response, "View dashboard should load")
|
173
|
+
|
174
|
+
# Check that the form is hidden by default
|
175
|
+
assert_match(/id="createPostSection".*style="[^"]*display: none[^"]*"/, response.body, "Create post form should be hidden by default")
|
176
|
+
|
177
|
+
# Check that the Create Post button exists
|
178
|
+
assert_match(/id="createPostButton".*Create Post/, response.body, "Create Post button should exist")
|
179
|
+
|
180
|
+
# Check that the form has Edit and Cancel buttons
|
181
|
+
assert_match(/button.*Edit/, response.body, "Form should have Edit button")
|
182
|
+
assert_match(/button.*Cancel/, response.body, "Form should have Cancel button")
|
183
|
+
|
184
|
+
# Check that view checkboxes exist
|
185
|
+
assert_match(/name="views\[\]"/, response.body, "Form should have view checkboxes")
|
186
|
+
end
|
187
|
+
|
188
|
+
def test_009_create_post_with_modal_redirect
|
189
|
+
start_web_server
|
190
|
+
setup_test_environment
|
191
|
+
|
192
|
+
# Create a post with the new form
|
193
|
+
response = post("/create_post", {
|
194
|
+
title: "Modal Test Post",
|
195
|
+
blurb: "Test post for modal",
|
196
|
+
tags: "test, modal",
|
197
|
+
views: ["test-view"]
|
198
|
+
})
|
199
|
+
|
200
|
+
# Should redirect to view with edit_post parameter
|
201
|
+
assert_response_redirect(response, "Should redirect after creating post")
|
202
|
+
assert_match(/edit_post=/, response['Location'], "Should redirect with edit_post parameter")
|
203
|
+
assert_match(/view\/test-view/, response['Location'], "Should redirect to view dashboard")
|
204
|
+
end
|
205
|
+
|
206
|
+
def test_010_post_content_api_endpoint
|
207
|
+
start_web_server
|
208
|
+
setup_test_environment
|
209
|
+
|
210
|
+
# Create a post first
|
211
|
+
create_response = post("/create_post", {
|
212
|
+
title: "API Test Post",
|
213
|
+
blurb: "Test post for API",
|
214
|
+
views: ["test-view"]
|
215
|
+
})
|
216
|
+
|
217
|
+
# Extract post ID from redirect
|
218
|
+
redirect_location = create_response['Location']
|
219
|
+
post_id = redirect_location.match(/edit_post=(\d+)/)[1]
|
220
|
+
|
221
|
+
# Test the API endpoint
|
222
|
+
api_response = get("/api/post_content/#{post_id}")
|
223
|
+
assert_response_success(api_response, "API endpoint should work")
|
224
|
+
|
225
|
+
# Should return the post content
|
226
|
+
assert_match(/API Test Post/, api_response.body, "API should return post content")
|
227
|
+
end
|
228
|
+
|
229
|
+
private
|
230
|
+
# All helper methods are now in WebTestHelper
|
231
|
+
end
|
@@ -0,0 +1,218 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'net/http'
|
4
|
+
require 'json'
|
5
|
+
require 'fileutils'
|
6
|
+
|
7
|
+
module WebTestHelper
|
8
|
+
# Web server configuration
|
9
|
+
WEB_SERVER_PORT = 4567
|
10
|
+
WEB_SERVER_URL = "http://localhost:#{WEB_SERVER_PORT}"
|
11
|
+
|
12
|
+
# Test repository path
|
13
|
+
TEST_REPO_PATH = "ui/web/scriptorium-TEST"
|
14
|
+
|
15
|
+
# Start web server in test mode
|
16
|
+
def start_web_server
|
17
|
+
# Check if server is already running
|
18
|
+
return if server_running?
|
19
|
+
|
20
|
+
# Kill any existing server on the port first
|
21
|
+
system("lsof -ti:#{WEB_SERVER_PORT} | xargs kill -9 2>/dev/null")
|
22
|
+
sleep(1) # Give it time to release the port
|
23
|
+
|
24
|
+
# Start the server
|
25
|
+
system("rbenv exec ruby ui/web/bin/scriptorium-web start --test")
|
26
|
+
wait_for_server
|
27
|
+
end
|
28
|
+
|
29
|
+
# Check if server is already running
|
30
|
+
def server_running?
|
31
|
+
begin
|
32
|
+
response = Net::HTTP.get_response(URI("#{WEB_SERVER_URL}/status"))
|
33
|
+
response.code == "200"
|
34
|
+
rescue
|
35
|
+
false
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
# Stop web server
|
40
|
+
def stop_web_server
|
41
|
+
system("rbenv exec ruby ui/web/bin/scriptorium-web stop")
|
42
|
+
end
|
43
|
+
|
44
|
+
# Wait for server to be ready
|
45
|
+
def wait_for_server(timeout = 15)
|
46
|
+
start_time = Time.now
|
47
|
+
last_error = nil
|
48
|
+
|
49
|
+
while Time.now - start_time < timeout
|
50
|
+
begin
|
51
|
+
response = Net::HTTP.get_response(URI("#{WEB_SERVER_URL}/status"))
|
52
|
+
if response.code == "200"
|
53
|
+
return true
|
54
|
+
end
|
55
|
+
rescue => e
|
56
|
+
last_error = e
|
57
|
+
# Server not ready yet
|
58
|
+
end
|
59
|
+
sleep 0.5
|
60
|
+
end
|
61
|
+
|
62
|
+
# If we get here, the server didn't start
|
63
|
+
error_msg = "Web server did not start within #{timeout} seconds"
|
64
|
+
if last_error
|
65
|
+
error_msg += " (last error: #{last_error.message})"
|
66
|
+
end
|
67
|
+
flunk error_msg
|
68
|
+
end
|
69
|
+
|
70
|
+
# Make GET request
|
71
|
+
def get(path, params = {})
|
72
|
+
uri = URI("#{WEB_SERVER_URL}#{path}")
|
73
|
+
uri.query = URI.encode_www_form(params) unless params.empty?
|
74
|
+
|
75
|
+
response = Net::HTTP.get_response(uri)
|
76
|
+
response
|
77
|
+
rescue => e
|
78
|
+
flunk "GET request failed: #{e.message}"
|
79
|
+
end
|
80
|
+
|
81
|
+
# Make POST request
|
82
|
+
def post(path, data = {})
|
83
|
+
uri = URI("#{WEB_SERVER_URL}#{path}")
|
84
|
+
|
85
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
86
|
+
request = Net::HTTP::Post.new(uri)
|
87
|
+
request.set_form_data(data)
|
88
|
+
|
89
|
+
response = http.request(request)
|
90
|
+
response
|
91
|
+
rescue => e
|
92
|
+
flunk "POST request failed: #{e.message}"
|
93
|
+
end
|
94
|
+
|
95
|
+
# Make PUT request
|
96
|
+
def put(path, data = {})
|
97
|
+
uri = URI("#{WEB_SERVER_URL}#{path}")
|
98
|
+
|
99
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
100
|
+
request = Net::HTTP::Put.new(uri)
|
101
|
+
request.set_form_data(data)
|
102
|
+
|
103
|
+
response = http.request(request)
|
104
|
+
response
|
105
|
+
rescue => e
|
106
|
+
flunk "PUT request failed: #{e.message}"
|
107
|
+
end
|
108
|
+
|
109
|
+
# Make DELETE request
|
110
|
+
def delete(path)
|
111
|
+
uri = URI("#{WEB_SERVER_URL}#{path}")
|
112
|
+
|
113
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
114
|
+
request = Net::HTTP::Delete.new(uri)
|
115
|
+
|
116
|
+
response = http.request(request)
|
117
|
+
response
|
118
|
+
rescue => e
|
119
|
+
flunk "DELETE request failed: #{e.message}"
|
120
|
+
end
|
121
|
+
|
122
|
+
# Assert response is successful (200)
|
123
|
+
def assert_response_success(response, description)
|
124
|
+
assert response, "Response should exist"
|
125
|
+
assert_equal "200", response.code, "#{description}: Expected 200, got #{response.code}"
|
126
|
+
end
|
127
|
+
|
128
|
+
# Assert response is redirect (302 or 303)
|
129
|
+
def assert_response_redirect(response, description)
|
130
|
+
assert response, "Response should exist"
|
131
|
+
assert ["302", "303"].include?(response.code), "#{description}: Expected 302 or 303, got #{response.code}"
|
132
|
+
end
|
133
|
+
|
134
|
+
# Assert response is not found (404)
|
135
|
+
def assert_response_not_found(response, description)
|
136
|
+
assert response, "Response should exist"
|
137
|
+
assert_equal "404", response.code, "#{description}: Expected 404, got #{response.code}"
|
138
|
+
end
|
139
|
+
|
140
|
+
# Assert that response body includes text, with concise error message
|
141
|
+
def assert_includes_concise(response, text, description)
|
142
|
+
unless response.body.include?(text)
|
143
|
+
# Show response size and a snippet for debugging
|
144
|
+
size = response.body.size
|
145
|
+
snippet = response.body[0, 300].gsub(/\s+/, ' ').strip
|
146
|
+
flunk "#{description} - Expected to find '#{text}' in response (#{size} bytes). Response snippet: #{snippet}..."
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
# Assert that a string includes text, with concise error message
|
151
|
+
def assert_includes_concise_string(content, text, description)
|
152
|
+
unless content.include?(text)
|
153
|
+
# Show content size and a snippet for debugging
|
154
|
+
size = content.size
|
155
|
+
snippet = content[0, 300].gsub(/\s+/, ' ').strip
|
156
|
+
flunk "#{description} - Expected to find '#{text}' in content (#{size} bytes). Content snippet: #{snippet}..."
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
# Parse JSON response
|
161
|
+
def parse_json_response(response)
|
162
|
+
return nil unless response.body
|
163
|
+
JSON.parse(response.body)
|
164
|
+
rescue JSON::ParserError => e
|
165
|
+
flunk "Failed to parse JSON response: #{e.message}"
|
166
|
+
end
|
167
|
+
|
168
|
+
# Clean up test repository
|
169
|
+
def cleanup_test_repo
|
170
|
+
FileUtils.rm_rf(TEST_REPO_PATH) if Dir.exist?(TEST_REPO_PATH)
|
171
|
+
# Also clean up backup directory for test repo
|
172
|
+
backup_dir = File.dirname(TEST_REPO_PATH) + "/backup-scriptorium-TEST"
|
173
|
+
FileUtils.rm_rf(backup_dir) if Dir.exist?(backup_dir)
|
174
|
+
end
|
175
|
+
|
176
|
+
# Setup basic test environment (repo + view)
|
177
|
+
def setup_test_environment
|
178
|
+
# Create repository
|
179
|
+
post("/create_repo", {})
|
180
|
+
|
181
|
+
# Create test view
|
182
|
+
post("/create_view", {
|
183
|
+
name: "test-view",
|
184
|
+
title: "Test View",
|
185
|
+
subtitle: "A test view for web testing"
|
186
|
+
})
|
187
|
+
end
|
188
|
+
|
189
|
+
# Wait for a specific condition with timeout
|
190
|
+
def wait_for_condition(timeout = 10, &block)
|
191
|
+
start_time = Time.now
|
192
|
+
while Time.now - start_time < timeout
|
193
|
+
if block.call
|
194
|
+
return true
|
195
|
+
end
|
196
|
+
sleep 0.5
|
197
|
+
end
|
198
|
+
flunk "Condition not met within #{timeout} seconds"
|
199
|
+
end
|
200
|
+
|
201
|
+
# Check if web app is in test mode
|
202
|
+
def assert_test_mode_active
|
203
|
+
response = get("/status")
|
204
|
+
data = parse_json_response(response)
|
205
|
+
assert data, "Should have status data"
|
206
|
+
assert_nil data["current_view"], "Should not have current view (test mode active)"
|
207
|
+
assert_equal false, data["repo_loaded"], "Should not have repo loaded (test mode active)"
|
208
|
+
end
|
209
|
+
|
210
|
+
# Verify test repository path is being used
|
211
|
+
def assert_test_repository_path
|
212
|
+
# This would require checking the web app's internal state
|
213
|
+
# For now, we verify by checking that no production data is visible
|
214
|
+
response = get("/")
|
215
|
+
assert_response_success(response, "Dashboard should load")
|
216
|
+
assert_includes_concise response, "No repository found", "Should show no repository (test mode)"
|
217
|
+
end
|
218
|
+
end
|