diff options
| author | Jim Porter | 2024-02-17 20:49:15 -0800 |
|---|---|---|
| committer | Jim Porter | 2024-03-06 14:36:23 -0800 |
| commit | 59e470dd5de6e75c4d3bb91c876c8540faf33fdb (patch) | |
| tree | 5dce2d1ef354996c9e7cb2d79bc19f87b126883a /test | |
| parent | b12059e4c320f374735a9c00975ef12cb964043f (diff) | |
| download | emacs-59e470dd5de6e75c4d3bb91c876c8540faf33fdb.tar.gz emacs-59e470dd5de6e75c4d3bb91c876c8540faf33fdb.zip | |
When navigating through history in EWW, don't keep adding to 'eww-history'
This resolves an issue where navigating back and then forward kept
adding new history entries so you could never hit the "end" (bug#69232).
* lisp/net/eww.el (eww-before-browse-history-function): New option.
(eww-history-position): Add docstring.
(eww-mode-map, eww-context-menu): Use correct predicates for when to
enable back/forward.
(eww-save-history): Save history entry in its original place when
viewing a historical page.
(eww--before-browse): New function...
(eww, eww-follow-link, eww-readable): ... call it.
(eww-render): Don't set 'eww-history-position' here...
(eww--before-browse): ... instead, set it here.
(eww-back-url): Set 'eww-history-position' based on the result of
'eww-save-history'.
(eww-forward-url): Set 'eww-history-position' directly, since
'eww-save-history' no longer adds a new entry in this case.
(eww-delete-future-history, eww-clone-previous-history): New functions.
* test/lisp/net/eww-tests.el: New file.
* etc/NEWS: Announce this change.
Diffstat (limited to 'test')
| -rw-r--r-- | test/lisp/net/eww-tests.el | 179 |
1 files changed, 179 insertions, 0 deletions
diff --git a/test/lisp/net/eww-tests.el b/test/lisp/net/eww-tests.el new file mode 100644 index 00000000000..ced84322e3a --- /dev/null +++ b/test/lisp/net/eww-tests.el | |||
| @@ -0,0 +1,179 @@ | |||
| 1 | ;;; eww-tests.el --- tests for eww.el -*- lexical-binding: t; -*- | ||
| 2 | |||
| 3 | ;; Copyright (C) 2024 Free Software Foundation, Inc. | ||
| 4 | |||
| 5 | ;; This file is part of GNU Emacs. | ||
| 6 | |||
| 7 | ;; GNU Emacs is free software: you can redistribute it and/or modify | ||
| 8 | ;; it under the terms of the GNU General Public License as published by | ||
| 9 | ;; the Free Software Foundation, either version 3 of the License, or | ||
| 10 | ;; (at your option) any later version. | ||
| 11 | |||
| 12 | ;; GNU Emacs is distributed in the hope that it will be useful, | ||
| 13 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 14 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 15 | ;; GNU General Public License for more details. | ||
| 16 | |||
| 17 | ;; You should have received a copy of the GNU General Public License | ||
| 18 | ;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. | ||
| 19 | |||
| 20 | ;;; Commentary: | ||
| 21 | |||
| 22 | ;;; Code: | ||
| 23 | |||
| 24 | (require 'ert) | ||
| 25 | (require 'eww) | ||
| 26 | |||
| 27 | (defvar eww-test--response-function (lambda (url) (concat "\n" url)) | ||
| 28 | "A function for returning a mock response for URL. | ||
| 29 | The default just returns an empty list of headers URL as the body.") | ||
| 30 | |||
| 31 | (defmacro eww-test--with-mock-retrieve (&rest body) | ||
| 32 | "Evaluate BODY with a mock implementation of `eww-retrieve'. | ||
| 33 | This avoids network requests during our tests. Additionally, prepare a | ||
| 34 | temporary EWW buffer for our tests." | ||
| 35 | (declare (indent 1)) | ||
| 36 | `(cl-letf (((symbol-function 'eww-retrieve) | ||
| 37 | (lambda (url callback args) | ||
| 38 | (with-temp-buffer | ||
| 39 | (insert (funcall eww-test--response-function url)) | ||
| 40 | (apply callback nil args))))) | ||
| 41 | (with-temp-buffer | ||
| 42 | (eww-mode) | ||
| 43 | ,@body))) | ||
| 44 | |||
| 45 | (defun eww-test--history-urls () | ||
| 46 | (mapcar (lambda (elem) (plist-get elem :url)) eww-history)) | ||
| 47 | |||
| 48 | ;;; Tests: | ||
| 49 | |||
| 50 | (ert-deftest eww-test/history/new-page () | ||
| 51 | "Test that when visiting a new page, the previous one goes into the history." | ||
| 52 | (eww-test--with-mock-retrieve | ||
| 53 | (eww "one.invalid") | ||
| 54 | (eww "two.invalid") | ||
| 55 | (should (equal (eww-test--history-urls) | ||
| 56 | '("http://one.invalid/"))) | ||
| 57 | (eww "three.invalid") | ||
| 58 | (should (equal (eww-test--history-urls) | ||
| 59 | '("http://two.invalid/" | ||
| 60 | "http://one.invalid/"))))) | ||
| 61 | |||
| 62 | (ert-deftest eww-test/history/back-forward () | ||
| 63 | "Test that navigating through history just changes our history position. | ||
| 64 | See bug#69232." | ||
| 65 | (eww-test--with-mock-retrieve | ||
| 66 | (eww "one.invalid") | ||
| 67 | (eww "two.invalid") | ||
| 68 | (eww "three.invalid") | ||
| 69 | (let ((url-history '("http://three.invalid/" | ||
| 70 | "http://two.invalid/" | ||
| 71 | "http://one.invalid/"))) | ||
| 72 | ;; Go back one page. This should add "three.invalid" to the | ||
| 73 | ;; history, making our position in the list 2. | ||
| 74 | (eww-back-url) | ||
| 75 | (should (equal (eww-test--history-urls) url-history)) | ||
| 76 | (should (= eww-history-position 2)) | ||
| 77 | ;; Go back again. | ||
| 78 | (eww-back-url) | ||
| 79 | (should (equal (eww-test--history-urls) url-history)) | ||
| 80 | (should (= eww-history-position 3)) | ||
| 81 | ;; At the beginning of the history, so trying to go back should | ||
| 82 | ;; signal an error. | ||
| 83 | (should-error (eww-back-url)) | ||
| 84 | ;; Go forward once. | ||
| 85 | (eww-forward-url) | ||
| 86 | (should (equal (eww-test--history-urls) url-history)) | ||
| 87 | (should (= eww-history-position 2)) | ||
| 88 | ;; Go forward again. | ||
| 89 | (eww-forward-url) | ||
| 90 | (should (equal (eww-test--history-urls) url-history)) | ||
| 91 | (should (= eww-history-position 1)) | ||
| 92 | ;; At the end of the history, so trying to go forward should | ||
| 93 | ;; signal an error. | ||
| 94 | (should-error (eww-forward-url))))) | ||
| 95 | |||
| 96 | (ert-deftest eww-test/history/reload-in-place () | ||
| 97 | "Test that reloading historical pages updates their history entry in-place. | ||
| 98 | See bug#69232." | ||
| 99 | (eww-test--with-mock-retrieve | ||
| 100 | (eww "one.invalid") | ||
| 101 | (eww "two.invalid") | ||
| 102 | (eww "three.invalid") | ||
| 103 | (eww-back-url) | ||
| 104 | ;; Make sure our history has the original page text. | ||
| 105 | (should (equal (plist-get (nth 1 eww-history) :text) | ||
| 106 | "http://two.invalid/")) | ||
| 107 | (should (= eww-history-position 2)) | ||
| 108 | ;; Reload the page. | ||
| 109 | (let ((eww-test--response-function | ||
| 110 | (lambda (url) (concat "\nreloaded " url)))) | ||
| 111 | (eww-reload) | ||
| 112 | (should (= eww-history-position 2))) | ||
| 113 | ;; Go to another page, and make sure the history is correct, | ||
| 114 | ;; including the reloaded page text. | ||
| 115 | (eww "four.invalid") | ||
| 116 | (should (equal (eww-test--history-urls) '("http://two.invalid/" | ||
| 117 | "http://one.invalid/"))) | ||
| 118 | (should (equal (plist-get (nth 0 eww-history) :text) | ||
| 119 | "reloaded http://two.invalid/")) | ||
| 120 | (should (= eww-history-position 0)))) | ||
| 121 | |||
| 122 | (ert-deftest eww-test/history/before-navigate/delete-future-history () | ||
| 123 | "Test that going to a new page from a historical one deletes future history. | ||
| 124 | See bug#69232." | ||
| 125 | (eww-test--with-mock-retrieve | ||
| 126 | (eww "one.invalid") | ||
| 127 | (eww "two.invalid") | ||
| 128 | (eww "three.invalid") | ||
| 129 | (eww-back-url) | ||
| 130 | (eww "four.invalid") | ||
| 131 | (eww "five.invalid") | ||
| 132 | (should (equal (eww-test--history-urls) '("http://four.invalid/" | ||
| 133 | "http://two.invalid/" | ||
| 134 | "http://one.invalid/"))) | ||
| 135 | (should (= eww-history-position 0)))) | ||
| 136 | |||
| 137 | (ert-deftest eww-test/history/before-navigate/ignore-history () | ||
| 138 | "Test that going to a new page from a historical one preserves history. | ||
| 139 | This sets `eww-before-browse-history-function' to `ignore' to preserve | ||
| 140 | history. See bug#69232." | ||
| 141 | (let ((eww-before-browse-history-function #'ignore)) | ||
| 142 | (eww-test--with-mock-retrieve | ||
| 143 | (eww "one.invalid") | ||
| 144 | (eww "two.invalid") | ||
| 145 | (eww "three.invalid") | ||
| 146 | (eww-back-url) | ||
| 147 | (eww "four.invalid") | ||
| 148 | (eww "five.invalid") | ||
| 149 | (should (equal (eww-test--history-urls) '("http://four.invalid/" | ||
| 150 | "http://three.invalid/" | ||
| 151 | "http://two.invalid/" | ||
| 152 | "http://one.invalid/"))) | ||
| 153 | (should (= eww-history-position 0))))) | ||
| 154 | |||
| 155 | (ert-deftest eww-test/history/before-navigate/clone-previous () | ||
| 156 | "Test that going to a new page from a historical one clones prior history. | ||
| 157 | This sets `eww-before-browse-history-function' to | ||
| 158 | `eww-clone-previous-history' to clone the history. See bug#69232." | ||
| 159 | (let ((eww-before-browse-history-function #'eww-clone-previous-history)) | ||
| 160 | (eww-test--with-mock-retrieve | ||
| 161 | (eww "one.invalid") | ||
| 162 | (eww "two.invalid") | ||
| 163 | (eww "three.invalid") | ||
| 164 | (eww-back-url) | ||
| 165 | (eww "four.invalid") | ||
| 166 | (eww "five.invalid") | ||
| 167 | (should (equal (eww-test--history-urls) | ||
| 168 | '(;; New page and cloned history. | ||
| 169 | "http://four.invalid/" | ||
| 170 | "http://two.invalid/" | ||
| 171 | "http://one.invalid/" | ||
| 172 | ;; Original history. | ||
| 173 | "http://three.invalid/" | ||
| 174 | "http://two.invalid/" | ||
| 175 | "http://one.invalid/"))) | ||
| 176 | (should (= eww-history-position 0))))) | ||
| 177 | |||
| 178 | (provide 'eww-tests) | ||
| 179 | ;; eww-tests.el ends here | ||