diff --git a/.editorconfig b/.editorconfig
index 919b41166..5b3c112c3 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -1,5 +1,5 @@
# Generated from:
-# https://github.com/plone/meta/tree/master/config/default
+# https://github.com/plone/meta/tree/main/config/default
# See the inline comments on how to expand/tweak this configuration file
#
# EditorConfig Configuration file, for more details see:
@@ -13,7 +13,8 @@
root = true
-[*] # For All Files
+[*]
+# Default settings for all files.
# Unix-style newlines with a newline ending every file
end_of_line = lf
insert_final_newline = true
@@ -29,13 +30,15 @@ max_line_length = off
# 4 space indentation
indent_size = 4
-[*.{yml,zpt,pt,dtml,zcml}]
+[*.{yml,zpt,pt,dtml,zcml,html,xml}]
# 2 space indentation
indent_size = 2
-[*.{json,jsonl,js,jsx,ts,tsx,css,less,scss,html}] # Frontend development
+[*.{json,jsonl,js,jsx,ts,tsx,css,less,scss}]
+# Frontend development
# 2 space indentation
indent_size = 2
+max_line_length = 80
[{Makefile,.gitmodules}]
# Tab indentation (no size specified, but view as 4 spaces)
diff --git a/.flake8 b/.flake8
index 7ef4f64d9..38918f42f 100644
--- a/.flake8
+++ b/.flake8
@@ -1,5 +1,5 @@
# Generated from:
-# https://github.com/plone/meta/tree/master/config/default
+# https://github.com/plone/meta/tree/main/config/default
# See the inline comments on how to expand/tweak this configuration file
[flake8]
doctests = 1
diff --git a/.github/workflows/meta.yml b/.github/workflows/meta.yml
index 4748f0f48..c9848bcbc 100644
--- a/.github/workflows/meta.yml
+++ b/.github/workflows/meta.yml
@@ -1,5 +1,5 @@
# Generated from:
-# https://github.com/plone/meta/tree/master/config/default
+# https://github.com/plone/meta/tree/main/config/default
# See the inline comments on how to expand/tweak this configuration file
name: Meta
on:
@@ -13,16 +13,63 @@ on:
- main
workflow_dispatch:
+##
+# To set environment variables for all jobs, add in .meta.toml:
+# [github]
+# env = """
+# debug: 1
+# image-name: 'org/image'
+# image-tag: 'latest'
+# """
+##
+
jobs:
qa:
- uses: plone/meta/.github/workflows/qa.yml@master
+ uses: plone/meta/.github/workflows/qa.yml@main
test:
- uses: plone/meta/.github/workflows/test.yml@master
+ uses: plone/meta/.github/workflows/test.yml@main
coverage:
- uses: plone/meta/.github/workflows/coverage.yml@master
+ uses: plone/meta/.github/workflows/coverage.yml@main
dependencies:
- uses: plone/meta/.github/workflows/dependencies.yml@master
- release-ready:
- uses: plone/meta/.github/workflows/release_ready.yml@master
+ uses: plone/meta/.github/workflows/dependencies.yml@main
+ release_ready:
+ uses: plone/meta/.github/workflows/release_ready.yml@main
circular:
- uses: plone/meta/.github/workflows/circular.yml@master
+ uses: plone/meta/.github/workflows/circular.yml@main
+
+##
+# To modify the list of default jobs being created add in .meta.toml:
+# [github]
+# jobs = [
+# "qa",
+# "test",
+# "coverage",
+# "dependencies",
+# "release_ready",
+# "circular",
+# ]
+##
+
+##
+# To request that some OS level dependencies get installed
+# when running tests/coverage jobs, add in .meta.toml:
+# [github]
+# os_dependencies = "git libxml2 libxslt"
+##
+
+##
+# To test against a specific matrix of python versions
+# when running tests jobs, add in .meta.toml:
+# [github]
+# py_versions = "['3.12', '3.11']"
+##
+
+
+##
+# Specify additional jobs in .meta.toml:
+# [github]
+# extra_lines = """
+# another:
+# uses: org/repo/.github/workflows/file.yml@main
+# """
+##
diff --git a/.gitignore b/.gitignore
index 81594fde9..486392f69 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,14 +1,18 @@
# Generated from:
-# https://github.com/plone/meta/tree/master/config/default
+# https://github.com/plone/meta/tree/main/config/default
# See the inline comments on how to expand/tweak this configuration file
# python related
*.egg-info
*.pyc
*.pyo
+# translation related
+*.mo
+
# tools related
build/
.coverage
+.*project
coverage.xml
dist/
docs/_build
@@ -31,6 +35,7 @@ lib64
parts/
pyvenv.cfg
var/
+local.cfg
# mxdev
/instance/
diff --git a/.meta.toml b/.meta.toml
index d3ded7c05..20de39039 100644
--- a/.meta.toml
+++ b/.meta.toml
@@ -1,10 +1,13 @@
# Generated from:
-# https://github.com/plone/meta/tree/master/config/default
+# https://github.com/plone/meta/tree/main/config/default
# See the inline comments on how to expand/tweak this configuration file
[meta]
template = "default"
-commit-id = "7723aeaf"
+commit-id = "a89af8f2"
[pyproject]
codespell_ignores = "oder,ist,crate"
-dependencies_ignores = "['ZServer', 'plone.app.event', 'Products.CFMPlone',]"
+dependencies_ignores = "['ZServer', 'plone.app.event', 'Products.CMFPlone',]"
+
+[tox]
+constraints_file = "https://dist.plone.org/release/6.1-dev/constraints.txt"
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 5ef2b8196..14603265d 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -1,5 +1,5 @@
# Generated from:
-# https://github.com/plone/meta/tree/master/config/default
+# https://github.com/plone/meta/tree/main/config/default
# See the inline comments on how to expand/tweak this configuration file
ci:
autofix_prs: false
@@ -7,20 +7,20 @@ ci:
repos:
- repo: https://github.com/asottile/pyupgrade
- rev: v3.4.0
+ rev: v3.17.0
hooks:
- id: pyupgrade
args: [--py38-plus]
- repo: https://github.com/pycqa/isort
- rev: 5.12.0
+ rev: 5.13.2
hooks:
- id: isort
- repo: https://github.com/psf/black
- rev: 23.3.0
+ rev: 24.8.0
hooks:
- id: black
- repo: https://github.com/collective/zpretty
- rev: 3.1.0a2
+ rev: 3.1.0
hooks:
- id: zpretty
@@ -32,11 +32,19 @@ repos:
# """
##
- repo: https://github.com/PyCQA/flake8
- rev: 6.0.0
+ rev: 7.1.1
hooks:
- id: flake8
+
+##
+# Add extra configuration options in .meta.toml:
+# [pre_commit]
+# flake8_extra_lines = """
+# _your own configuration lines_
+# """
+##
- repo: https://github.com/codespell-project/codespell
- rev: v2.2.4
+ rev: v2.3.0
hooks:
- id: codespell
additional_dependencies:
@@ -58,15 +66,25 @@ repos:
hooks:
- id: pyroma
- repo: https://github.com/mgedmin/check-python-versions
- rev: "0.21.2"
+ rev: "0.22.0"
hooks:
- id: check-python-versions
args: ['--only', 'setup.py,pyproject.toml']
- repo: https://github.com/collective/i18ndude
- rev: "6.0.0"
+ rev: "6.2.1"
hooks:
- id: i18ndude
+
+##
+# Add extra configuration options in .meta.toml:
+# [pre_commit]
+# i18ndude_extra_lines = """
+# _your own configuration lines_
+# """
+##
+
+
##
# Add extra configuration options in .meta.toml:
# [pre_commit]
diff --git a/CHANGES.rst b/CHANGES.rst
index 61f1f758d..deafacf09 100644
--- a/CHANGES.rst
+++ b/CHANGES.rst
@@ -8,6 +8,86 @@ Changelog
.. towncrier release notes start
+4.0.0 (2024-09-03)
+------------------
+
+Breaking changes:
+
+
+- Do not enable plone.allowdiscussion by default, it is a core add-on now.
+ This is for Plone 6.1, so is a breaking change.
+ [@jensens] (#665)
+
+
+3.0.9 (2024-06-07)
+------------------
+
+Bug fixes:
+
+
+- No longer set ``portal_properties.site_properties.visible_ids`` on site creation.
+ The ``portal_properties`` tools is deprecated, ``visible_ids`` was not set as real property, and usage of ``visible_ids`` was largely removed in Plone 5.0 already.
+ You already can no longer set ``visible ids`` in the Editing control panel, nor in the member preferences.
+ The only remaining use for ``visible_ids``, if set to true, was to show the page ids on the 'select default page' form.
+ [maurits] (#125)
+
+
+3.0.8 (2024-05-30)
+------------------
+
+Bug fixes:
+
+
+- Support using the file template on objects that have no file attributes. [ale-rt] (#688)
+- Fixed p.a.widgets `moved` DeprecationWarning [jensens] (#690)
+
+
+3.0.7 (2024-04-25)
+------------------
+
+Bug fixes:
+
+
+- Fix ILeadImageBehavior and IRichTextBehavior interfaces were the name change was forgotten.
+ [thet] (#681)
+
+
+3.0.6 (2024-03-15)
+------------------
+
+Bug fixes:
+
+
+- Fix folder listing template when `plone.eventlocation` behavior is disabled for Events.
+ [petschki] (#679)
+
+
+Internal:
+
+
+- Update configuration files.
+ [plone devs] (6e36bcc4)
+
+
+3.0.5 (2023-10-25)
+------------------
+
+Bug fixes:
+
+
+- Fix link_redirect_view, respect vhm vs none-vhm url schemes @1letter (#671)
+
+
+3.0.4 (2023-10-07)
+------------------
+
+Internal:
+
+
+- Update configuration files.
+ [plone devs] (7723aeaf)
+
+
3.0.3 (2023-05-22)
------------------
@@ -437,7 +517,7 @@ Bug fixes:
New features:
-- Support ILeadImage behavior when display collection album view.
+- Support ILeadImageBehavior when display collection album view.
[rodfersou] (#524)
- Add more log-messages during migration from AT to DX.
[pbauer] (#526)
@@ -516,7 +596,7 @@ Bug fixes:
Breaking changes:
-- ILeadImage and IRichText behaviors now have proper "Marker"-Interfaces.
+- ILeadImageBehavior and IRichTextBehavior behaviors now have proper "Marker"-Interfaces.
As this was only possible by renaming the schema adapter to *Behavior* to
not break with implementations inside the collective, the FTI-behavior-definition
has changed:
@@ -770,7 +850,7 @@ New features:
Bug fixes:
-- Add translation namesspace and i18n:translate to the dexterity schema
+- Add translation namespace and i18n:translate to the dexterity schema
definitions for the content types that have extra field defined on top of the
behavior composition. Otherwise no translations can be picked up.
[fredvd]
diff --git a/dependabot.yml b/dependabot.yml
new file mode 100644
index 000000000..bbd3ab050
--- /dev/null
+++ b/dependabot.yml
@@ -0,0 +1,11 @@
+# Generated from:
+# https://github.com/plone/meta/tree/main/config/default
+# See the inline comments on how to expand/tweak this configuration file
+version: 2
+updates:
+
+ - package-ecosystem: "github-actions"
+ directory: "/"
+ schedule:
+ # Check for updates to GitHub Actions every week
+ interval: "weekly"
diff --git a/docs/README.rst b/docs/README.rst
index c734665e9..84ad8b02a 100644
--- a/docs/README.rst
+++ b/docs/README.rst
@@ -79,7 +79,7 @@ You have several options:
@@ -91,7 +91,7 @@ You have several options:
@@ -122,7 +122,7 @@ You have several options:
-You could alternatively override the peroperty ``model_file`` of the type-definition with a empty string and use the property ``schema`` to provide your custom python-schema.
+You could alternatively override the property ``model_file`` of the type-definition with a empty string and use the property ``schema`` to provide your custom python-schema.
For more complex features you should always consider create custom behaviors and/or write your own content-types since that will most likely give you more flexibility and less problem when you want to upgrade to a newer version in the future.
diff --git a/news/3813.bugfix b/news/3813.bugfix
new file mode 100644
index 000000000..7b6bc3f35
--- /dev/null
+++ b/news/3813.bugfix
@@ -0,0 +1,2 @@
+Port robot tests to playwright.
+[gforcada]
diff --git a/news/7723aeaf.internal b/news/7723aeaf.internal
deleted file mode 100644
index c08f53991..000000000
--- a/news/7723aeaf.internal
+++ /dev/null
@@ -1,2 +0,0 @@
-Update configuration files.
-[plone devs]
diff --git a/plone/app/contenttypes/behaviors/collection.py b/plone/app/contenttypes/behaviors/collection.py
index 2e97c06ab..ee64cdb9b 100644
--- a/plone/app/contenttypes/behaviors/collection.py
+++ b/plone/app/contenttypes/behaviors/collection.py
@@ -1,5 +1,5 @@
from plone.app.contenttypes import _
-from plone.app.z3cform.widget import QueryStringFieldWidget
+from plone.app.z3cform.widgets.querystring import QueryStringFieldWidget
from plone.autoform import directives as form
from plone.autoform.interfaces import IFormFieldProvider
from plone.base.interfaces.syndication import IFeed
diff --git a/plone/app/contenttypes/behaviors/richtext.py b/plone/app/contenttypes/behaviors/richtext.py
index adc38d5f5..840311c66 100644
--- a/plone/app/contenttypes/behaviors/richtext.py
+++ b/plone/app/contenttypes/behaviors/richtext.py
@@ -2,7 +2,7 @@
from plone.app.contenttypes import _
from plone.app.dexterity.textindexer import searchable
from plone.app.textfield import RichText as RichTextField
-from plone.app.z3cform.widget import RichTextFieldWidget
+from plone.app.z3cform.widgets.richtext import RichTextFieldWidget
from plone.autoform import directives as form
from plone.autoform.interfaces import IFormFieldProvider
from plone.autoform.view import WidgetsView
diff --git a/plone/app/contenttypes/behaviors/viewlets.py b/plone/app/contenttypes/behaviors/viewlets.py
index eb38dbb25..8fe6a8def 100644
--- a/plone/app/contenttypes/behaviors/viewlets.py
+++ b/plone/app/contenttypes/behaviors/viewlets.py
@@ -1,4 +1,4 @@
-from plone.app.contenttypes.behaviors.leadimage import ILeadImage
+from plone.app.contenttypes.behaviors.leadimage import ILeadImageBehavior
from plone.app.layout.viewlets import ViewletBase
@@ -6,5 +6,5 @@ class LeadImageViewlet(ViewletBase):
"""A simple viewlet which renders leadimage"""
def update(self):
- self.context = ILeadImage(self.context)
- self.available = True if self.context.image else False
+ behavior = ILeadImageBehavior(self.context)
+ self.available = True if behavior.image else False
diff --git a/plone/app/contenttypes/browser/configure.zcml b/plone/app/contenttypes/browser/configure.zcml
index ae3464175..b3e2c7ba3 100644
--- a/plone/app/contenttypes/browser/configure.zcml
+++ b/plone/app/contenttypes/browser/configure.zcml
@@ -97,7 +97,7 @@
-
+
+
+
-
diff --git a/plone/app/contenttypes/browser/templates/listing.pt b/plone/app/contenttypes/browser/templates/listing.pt
index 9e2d7553f..9ad3df226 100644
--- a/plone/app/contenttypes/browser/templates/listing.pt
+++ b/plone/app/contenttypes/browser/templates/listing.pt
@@ -93,7 +93,7 @@
-
—
diff --git a/plone/app/contenttypes/indexers.py b/plone/app/contenttypes/indexers.py
index a4e495178..973dfe83b 100644
--- a/plone/app/contenttypes/indexers.py
+++ b/plone/app/contenttypes/indexers.py
@@ -1,6 +1,6 @@
from Acquisition import aq_base
from logging import getLogger
-from plone.app.contenttypes.behaviors.richtext import IRichText
+from plone.app.contenttypes.behaviors.richtext import IRichTextBehavior
from plone.app.contenttypes.interfaces import ICollection
from plone.app.contenttypes.interfaces import IDocument
from plone.app.contenttypes.interfaces import IFile
@@ -40,7 +40,7 @@ def _unicode_save_string_concat(*args):
def SearchableText(obj):
text = ""
- richtext = IRichText(obj, None)
+ richtext = IRichTextBehavior(obj, None)
if richtext:
textvalue = richtext.text
if IRichTextValue.providedBy(textvalue):
diff --git a/plone/app/contenttypes/profiles/default/types/Collection.xml b/plone/app/contenttypes/profiles/default/types/Collection.xml
index 05c04bab9..9b0e322dc 100644
--- a/plone/app/contenttypes/profiles/default/types/Collection.xml
+++ b/plone/app/contenttypes/profiles/default/types/Collection.xml
@@ -36,7 +36,6 @@
>
-
diff --git a/plone/app/contenttypes/profiles/default/types/Document.xml b/plone/app/contenttypes/profiles/default/types/Document.xml
index 76da466b6..d72793d5d 100644
--- a/plone/app/contenttypes/profiles/default/types/Document.xml
+++ b/plone/app/contenttypes/profiles/default/types/Document.xml
@@ -35,7 +35,6 @@
purge="false"
>
-
diff --git a/plone/app/contenttypes/profiles/default/types/File.xml b/plone/app/contenttypes/profiles/default/types/File.xml
index a9b9211b0..e99741593 100644
--- a/plone/app/contenttypes/profiles/default/types/File.xml
+++ b/plone/app/contenttypes/profiles/default/types/File.xml
@@ -38,7 +38,6 @@
-
diff --git a/plone/app/contenttypes/profiles/default/types/Folder.xml b/plone/app/contenttypes/profiles/default/types/Folder.xml
index e42362888..4d37fbcad 100644
--- a/plone/app/contenttypes/profiles/default/types/Folder.xml
+++ b/plone/app/contenttypes/profiles/default/types/Folder.xml
@@ -36,7 +36,6 @@
>
-
diff --git a/plone/app/contenttypes/profiles/default/types/Image.xml b/plone/app/contenttypes/profiles/default/types/Image.xml
index 90b223c8f..cc069e93a 100644
--- a/plone/app/contenttypes/profiles/default/types/Image.xml
+++ b/plone/app/contenttypes/profiles/default/types/Image.xml
@@ -37,7 +37,6 @@
-
diff --git a/plone/app/contenttypes/profiles/default/types/Link.xml b/plone/app/contenttypes/profiles/default/types/Link.xml
index 33fa21f45..581f98dde 100644
--- a/plone/app/contenttypes/profiles/default/types/Link.xml
+++ b/plone/app/contenttypes/profiles/default/types/Link.xml
@@ -34,7 +34,6 @@
-
diff --git a/plone/app/contenttypes/profiles/default/types/News_Item.xml b/plone/app/contenttypes/profiles/default/types/News_Item.xml
index 0ddebb6f3..a706f5c94 100644
--- a/plone/app/contenttypes/profiles/default/types/News_Item.xml
+++ b/plone/app/contenttypes/profiles/default/types/News_Item.xml
@@ -37,7 +37,6 @@
-
diff --git a/plone/app/contenttypes/setuphandlers.py b/plone/app/contenttypes/setuphandlers.py
index f1b881450..d312d862f 100644
--- a/plone/app/contenttypes/setuphandlers.py
+++ b/plone/app/contenttypes/setuphandlers.py
@@ -9,7 +9,6 @@
from plone.base.utils import unrestricted_construct_instance
from plone.dexterity.fti import IDexterityFTI
from plone.dexterity.utils import createContent
-from plone.i18n.normalizer.interfaces import IURLNormalizer
from plone.portlets.interfaces import ILocalPortletAssignmentManager
from plone.portlets.interfaces import IPortletManager
from plone.registry.interfaces import IRegistry
@@ -131,25 +130,6 @@ def _setup_calendar(portal, locale):
portal_calendar.firstweekday = first
-def _setup_visible_ids(portal, target_language, locale):
- portal_properties = getToolByName(portal, "portal_properties")
- site_properties = portal_properties.site_properties
-
- # See if we have a URL normalizer
- normalizer = queryUtility(IURLNormalizer, name=target_language)
- if normalizer is None:
- normalizer = queryUtility(IURLNormalizer)
-
- # If we get a script other than Latn we enable visible_ids
- if locale.id.script is not None:
- if locale.id.script.lower() != "latn":
- site_properties.visible_ids = True
-
- # If we have a normalizer it is safe to disable the visible ids
- if normalizer is not None:
- site_properties.visible_ids = False
-
-
def _setup_constrains(container, allowed_types):
behavior = ISelectableConstrainTypes(container)
behavior.setConstrainTypesMode(constrains.ENABLED)
@@ -361,7 +341,6 @@ def setup_various(context):
portal = getSite()
target_language, is_combined_language, locale = _get_locales_info(portal)
_setup_calendar(portal, locale)
- _setup_visible_ids(portal, target_language, locale)
# install explicitly the plone.app.event
if HAS_EVENT:
diff --git a/plone/app/contenttypes/tests/robot/keywords.txt b/plone/app/contenttypes/tests/robot/keywords.txt
index 2f204e59b..2706a278e 100644
--- a/plone/app/contenttypes/tests/robot/keywords.txt
+++ b/plone/app/contenttypes/tests/robot/keywords.txt
@@ -34,11 +34,10 @@ a event
a file
[Arguments] ${title}
Go to ${PLONE_URL}/++add++File
- Wait until page contains Add File
- Input text name=form.widgets.title ${title}
+ Fill text name=form.widgets.title ${title}
Choose File name=form.widgets.file ${PATH_TO_TEST_FILES}/file.pdf
- Wait For Then Click Element css=#form-buttons-save
- Wait until page contains Item created
+ Click css=#form-buttons-save
+ Get text body contains Item created
a folder
[Arguments] ${title}
@@ -48,11 +47,10 @@ a folder
a image
[Arguments] ${title}
Go to ${PLONE_URL}/++add++Image
- Wait until page contains Add Image
- Input text name=form.widgets.title ${title}
+ Fill text name=form.widgets.title ${title}
Choose File name=form.widgets.image ${PATH_TO_TEST_FILES}/image.png
- Wait For Then Click Element css=#form-buttons-save
- Wait until page contains Item created error=Image could not be created.
+ Click css=#form-buttons-save
+ Get text body contains Item created
a link
[Arguments] ${title}
@@ -63,10 +61,9 @@ a link
a news item
[Arguments] ${title}
Go to ${PLONE_URL}/++add++News Item
- Wait until page contains Add News Item
- Input text name=form.widgets.IDublinCore.title ${title}
- Wait For Then Click Element css=#form-buttons-save
- Wait until page contains Item created
+ Fill text css=[name="form.widgets.IDublinCore.title"] ${title}
+ Click css=#form-buttons-save
+ Get text body contains Item created
# ----------------------------------------------------------------------------
@@ -75,17 +72,15 @@ a news item
the content area should contain
[Arguments] ${text}
- Element Should Contain id=content ${text}
+ Get text id=content contains ${text}
the content area should not contain
[Arguments] ${text}
- Element Should Not Contain id=content ${text}
+ Get Text id=content != ${text}
the collection should contain
[Arguments] ${title}
- Wait until page contains element xpath=//*[@id='content-core']
- Page should contain element //*[@id='content-core']//article//a[contains(text(), '${title}')] limit=1
-
+ Get Element //*[@id='content-core']//article//a[contains(text(), '${title}')]
the collection should not contain
[Arguments] ${title}
@@ -101,34 +96,22 @@ fill date field
Click Element xpath=//div[@data-fieldname="${fieldid}"]//div[contains(@class, 'picker__day')][contains(text(), "${day}")]
I set the criteria ${type} in row ${number} to the option '${label}'
- [Documentation] A couple of times we shift the focus so the input sticks, and wait a bit,
- ... to make the test more stable.
${criteria_row} = Convert to String .querystring-criteria-wrapper:nth-child(${number})
- Wait until page contains element css=${criteria_row} .querystring-criteria-${type} .select2-choice
- Click Element css=${criteria_row} .querystring-criteria-${type} .select2-choice
- Sleep 1.5
- Set Focus To Element css=body
- Wait until element is visible css=#select2-drop input
- Input Text css=#select2-drop input ${label}
- Sleep 1.5
- Set Focus To Element css=body
- Wait until element is visible css=#select2-drop .select2-match
- Click Element css=#select2-drop .select2-match
- Sleep 1.5
- Set Focus To Element css=body
+ Click css=${criteria_row} .querystring-criteria-${type} .select2-choice
+ Fill Text css=#select2-drop input ${label}
+ Click xpath=//*[@id="select2-drop"]//*[@class="select2-match"]
I set the criteria ${type} in row ${number} to the options '${label}'
- ${criteria_row} = Convert to String .querystring-criteria-wrapper:nth-child(${number})
- Wait until page contains element css=${criteria_row} .querystring-criteria-${type} .select2-choices
- Click Element css=${criteria_row} .querystring-criteria-${type} .select2-choices
- Wait until page contains element css=.select2-input.select2-focused
- Input text css=.select2-input.select2-focused ${label}\n
-# Click Element xpath=//div[@class='select2-result-label']/descendant-or-self::*[contains(text(), '${label}')]
+ ${criteria_row} = Convert to String .querystring-criteria-wrapper:nth-child(1)
+ Click css=${criteria_row} .querystring-criteria-value .select2-choices
+ Fill text css=.select2-input.select2-focused ${label}\n
+ Click css=.select2-highlighted
+ Get text css=${criteria_row} .select2-search-choice contains ${label}
+ [Documentation] Chrome needs some more time
+ Sleep .1s
I set the criteria ${type} in row ${number} to the text '${label}'
${criteria_row} = Convert to String .querystring-criteria-wrapper:nth-child(${number})
- Input text css=${criteria_row} .querystring-criteria-value input ${label}\t
- [Documentation] Shift the focus so the input sticks, and wait a bit
- Sleep 1.5
- Set Focus To Element css=.querystring-sortreverse
- Sleep 1.5
+ Fill text css=${criteria_row} .querystring-criteria-value input ${label}
+ Click css=.autotoc-level-1.active
+ Sleep 1s
diff --git a/plone/app/contenttypes/tests/robot/test_collection_creator_criterion.robot b/plone/app/contenttypes/tests/robot/test_collection_creator_criterion.robot
index b957e8699..885336548 100644
--- a/plone/app/contenttypes/tests/robot/test_collection_creator_criterion.robot
+++ b/plone/app/contenttypes/tests/robot/test_collection_creator_criterion.robot
@@ -1,18 +1,7 @@
-# ============================================================================
-# Tests for the Collection Creator Criterion
-# ============================================================================
-#
-# $ bin/robot-server --reload-path src/plone.app.contenttypes plone.app.contenttypes.testing.PLONE_APP_CONTENTTYPES_ROBOT_TESTING
-#
-# $ bin/robot src/plone.app.contenttypes/plone/app/contenttypes/tests/robot/test_collection_creator_criterion.robot
-#
-# ============================================================================
-
-*** Settings *****************************************************************
-
-Resource plone/app/robotframework/keywords.robot
-Resource plone/app/robotframework/saucelabs.robot
-Resource plone/app/robotframework/selenium.robot
+*** Settings ***
+
+Resource plone/app/robotframework/browser.robot
+Resource plone/app/robotframework/user.robot
Resource keywords.txt
Library Remote ${PLONE_URL}/RobotRemote
@@ -20,7 +9,6 @@ Library Remote ${PLONE_URL}/RobotRemote
Test Setup Run Keywords Plone test setup
Test Teardown Run keywords Plone test teardown
-
*** Test cases ***************************************************************
Scenario: Test Creator Criterions
@@ -49,11 +37,10 @@ a test user document
I set the collection's creator criterion to the current logged in user
Go to ${PLONE_URL}/my-collection/edit
- Wait until page contains Edit Collection
+ Get Text body contains Edit Collection
I set the criteria index in row 1 to the option 'Creator'
I set the criteria operator in row 1 to the option 'Current'
- Sleep 1
- Click Button Save
- Wait until page contains Changes saved
+ Click "Save"
+ Get Text body contains Changes saved
diff --git a/plone/app/contenttypes/tests/robot/test_collection_location_criterion.robot b/plone/app/contenttypes/tests/robot/test_collection_location_criterion.robot
index eb2dc7522..2ce5421f5 100644
--- a/plone/app/contenttypes/tests/robot/test_collection_location_criterion.robot
+++ b/plone/app/contenttypes/tests/robot/test_collection_location_criterion.robot
@@ -1,18 +1,6 @@
-# ============================================================================
-# Tests for the Collection Location Criterion
-# ============================================================================
-#
-# $ bin/robot-server --reload-path src/plone.app.contenttypes plone.app.contenttypes.testing.PLONE_APP_CONTENTTYPES_ROBOT_TESTING
-#
-# $ bin/robot src/plone.app.contenttypes/plone/app/contenttypes/tests/robot/test_collection_location_criterion.robot
-#
-# ============================================================================
-
-*** Settings *****************************************************************
-
-Resource plone/app/robotframework/keywords.robot
-Resource plone/app/robotframework/saucelabs.robot
-Resource plone/app/robotframework/selenium.robot
+*** Settings ***
+
+Resource plone/app/robotframework/browser.robot
Resource keywords.txt
Variables variables.py
@@ -21,11 +9,9 @@ Test Setup Run Keywords Plone test setup
Test Teardown Run keywords Plone test teardown
-*** Test cases ***************************************************************
+*** Test cases ***
Scenario: Test Relative Location Criterion
- [Documentation] This sometimes fails with:
- ... Element locator 'css=#select2-drop input' did not match any elements after 30 seconds
Given I am logged in as site owner
And a document Document outside Folder
And a folder 'my-folder' with a document 'Document within Folder'
@@ -36,9 +22,6 @@ Scenario: Test Relative Location Criterion
Scenario: Test Absolute Location Criterion
- [Documentation] This sometimes fails with:
- ... Element locator 'css=#select2-drop input' did not match any elements after 30 seconds
- ... Or with: Element 'id=content' should not contain text 'Document outside Folder' but it did.
Given I am logged in as site owner
And a document Document outside Folder
And a folder 'my-folder' with a document 'Document within Folder'
@@ -52,14 +35,14 @@ Scenario: Test Absolute Location Criterion
a folder '${folder-id}' with a document '${document-title}'
Go to ${PLONE_URL}/++add++Folder
- Wait until page contains element name=form.widgets.IDublinCore.title
- Input text name=form.widgets.IDublinCore.title ${folder-id}
- Click Button Save
+ # Wait until page contains element name=form.widgets.IDublinCore.title
+ Fill text xpath=//*[@name="form.widgets.IDublinCore.title"] ${folder-id}
+ Click "Save"
Go to ${PLONE_URL}/${folder-id}/++add++Document
- Wait until page contains element name=form.widgets.IDublinCore.title
- Input text name=form.widgets.IDublinCore.title ${document-title}
- Click Button Save
- Wait until page contains Item created
+ # Wait until page contains element name=form.widgets.IDublinCore.title
+ Fill text xpath=//*[@name="form.widgets.IDublinCore.title"] ${document-title}
+ Click "Save"
+ # Wait until page contains Item created
I set the collection's location criterion to Advanced Mode
I set the criteria operator in row 1 to the option 'Advanced Mode'
@@ -67,7 +50,7 @@ I set the collection's location criterion to Advanced Mode
I set the collection's relative location criterion to
[Arguments] ${criterion}
Go to ${PLONE_URL}/my-collection/edit
- Wait until page contains Edit Collection
+ # Wait until page contains Edit Collection
I set the criteria index in row 1 to the option 'Location'
@@ -76,13 +59,13 @@ I set the collection's relative location criterion to
I set the criteria operator in row 1 to the option 'Relative path'
I set the criteria value in row 1 to the text '${criterion}'
- Click Button Save
- Wait until page contains Changes saved
+ Click "Save"
+ # Wait until page contains Changes saved
I set the collection's absolute location criterion to
[Arguments] ${criterion}
Go to ${PLONE_URL}/my-collection/edit
- Wait until page contains Edit Collection
+ # Wait until page contains Edit Collection
I set the criteria index in row 1 to the option 'Location'
@@ -91,5 +74,5 @@ I set the collection's absolute location criterion to
I set the criteria operator in row 1 to the option 'Absolute path'
I set the criteria value in row 1 to the text '${criterion}'
- Click Button Save
- Wait until page contains Changes saved
+ Click "Save"
+ # Wait until page contains Changes saved
diff --git a/plone/app/contenttypes/tests/robot/test_collection_review_state_criterion.robot b/plone/app/contenttypes/tests/robot/test_collection_review_state_criterion.robot
index 719d7f975..bd4b7fe20 100644
--- a/plone/app/contenttypes/tests/robot/test_collection_review_state_criterion.robot
+++ b/plone/app/contenttypes/tests/robot/test_collection_review_state_criterion.robot
@@ -1,25 +1,15 @@
-# ============================================================================
-# Tests for the Collection Type Criterion
-# ============================================================================
-#
-# $ bin/robot-server --reload-path src/plone.app.contenttypes plone.app.contenttypes.testing.PLONE_APP_CONTENTTYPES_ROBOT_TESTING
-#
-# $ bin/robot src/plone.app.contenttypes/plone/app/contenttypes/tests/robot/test_collection_review_state_criterion.robot
-#
-# ============================================================================
-
-*** Settings *****************************************************************
-
-Resource plone/app/robotframework/keywords.robot
-Resource plone/app/robotframework/saucelabs.robot
-Resource plone/app/robotframework/selenium.robot
+*** Settings ***
+
+Resource plone/app/robotframework/browser.robot
Resource keywords.txt
+Variables variables.py
+
Test Setup Run Keywords Plone test setup
Test Teardown Run keywords Plone test teardown
-*** Test cases ***************************************************************
+*** Test cases ***
Scenario: Test Review state Criterion
Given I am logged in as site owner
@@ -45,12 +35,9 @@ a private document
I set the collection's review state criterion to
[Arguments] ${criterion}
Go to ${PLONE_URL}/my-collection/edit
- Wait until page contains Edit Collection
I set the criteria index in row 1 to the option 'Review state'
I set the criteria operator in row 1 to the option 'Any'
I set the criteria value in row 1 to the options '${criterion}'
- Sleep 1
- Click Button Save
- Wait until page contains Changes saved
+ Click "Save"
diff --git a/plone/app/contenttypes/tests/robot/test_collection_short_name_criterion.robot b/plone/app/contenttypes/tests/robot/test_collection_short_name_criterion.robot
index cf09f2775..97246a9fe 100644
--- a/plone/app/contenttypes/tests/robot/test_collection_short_name_criterion.robot
+++ b/plone/app/contenttypes/tests/robot/test_collection_short_name_criterion.robot
@@ -1,25 +1,15 @@
-# ============================================================================
-# Tests for the Collection Short Name Criterion
-# ============================================================================
-#
-# $ bin/robot-server --reload-path src/plone.app.contenttypes plone.app.contenttypes.testing.PLONE_APP_CONTENTTYPES_ROBOT_TESTING
-#
-# $ bin/robot src/plone.app.contenttypes/plone/app/contenttypes/tests/robot/test_collection_short_name_criterion.robot
-#
-# ============================================================================
-
-*** Settings *****************************************************************
-
-Resource plone/app/robotframework/keywords.robot
-Resource plone/app/robotframework/saucelabs.robot
-Resource plone/app/robotframework/selenium.robot
+*** Settings ***
+
+Resource plone/app/robotframework/browser.robot
Resource keywords.txt
+Variables variables.py
+
Test Setup Run Keywords Plone test setup
Test Teardown Run keywords Plone test teardown
-*** Test cases ***************************************************************
+*** Test cases ***
Test Short name (id) Criterion
Given I am logged in as site owner
@@ -36,12 +26,19 @@ Test Short name (id) Criterion
I set the collection short name (id) criterion to
[Arguments] ${criterion}
Go to ${PLONE_URL}/my-collection/edit
- Wait until page contains Edit Collection
I set the criteria index in row 1 to the option 'Short name'
- I set the criteria operator in row 1 to the option 'Is'
+ #I set the criteria operator in row 1 to the option 'Is'
+
+ ${criteria_row} = Convert to String .querystring-criteria-wrapper:nth-child(1)
+ Click css=${criteria_row} .querystring-criteria-operator .select2-choice
+ Fill Text css=#select2-drop input Is
+ Click css=.select2-highlighted
+
+
I set the criteria value in row 1 to the text '${criterion}'
+ [Documentation] Chrome needs some more time
+ Sleep .1s
- Sleep 1
- Click Button Save
- Wait until page contains Changes saved
+ Click "Save"
+ Get text body contains Changes saved
diff --git a/plone/app/contenttypes/tests/robot/test_collection_type_criterion.robot b/plone/app/contenttypes/tests/robot/test_collection_type_criterion.robot
index d7a2bbf61..774a798d9 100644
--- a/plone/app/contenttypes/tests/robot/test_collection_type_criterion.robot
+++ b/plone/app/contenttypes/tests/robot/test_collection_type_criterion.robot
@@ -1,25 +1,14 @@
-# ============================================================================
-# Tests for the Collection Type Criterion
-# ============================================================================
-#
-# $ bin/robot-server --reload-path src/plone.app.contenttypes plone.app.contenttypes.testing.PLONE_APP_CONTENTTYPES_ROBOT_TESTING
-#
-# $ bin/robot src/plone.app.contenttypes/plone/app/contenttypes/tests/robot/test_collection_type_criterion.robot
-#
-# ============================================================================
-
-*** Settings *****************************************************************
-
-Resource plone/app/robotframework/keywords.robot
-Resource plone/app/robotframework/saucelabs.robot
-Resource plone/app/robotframework/selenium.robot
+*** Settings ***
+
+Resource plone/app/robotframework/browser.robot
Resource keywords.txt
+Variables variables.py
+
Test Setup Run Keywords Plone test setup
Test Teardown Run keywords Plone test teardown
-
-*** Test cases ***************************************************************
+*** Test cases ***
Test Type Criterion
Given I am logged in as site owner
@@ -36,12 +25,10 @@ Test Type Criterion
I set the collection's type criterion to
[Arguments] ${criterion}
Go to ${PLONE_URL}/my-collection/edit
- Wait until page contains Edit Collection
I set the criteria index in row 1 to the option 'Type'
I set the criteria operator in row 1 to the option 'Any'
I set the criteria value in row 1 to the options '${criterion}'
- Sleep 1
- Click Button Save
- Wait until page contains Changes saved
+ Click "Save"
+ Get text body contains Changes saved
diff --git a/plone/app/contenttypes/tests/robot/test_folderlisting.robot b/plone/app/contenttypes/tests/robot/test_folderlisting.robot
index a64f535d6..2cfb53fa7 100644
--- a/plone/app/contenttypes/tests/robot/test_folderlisting.robot
+++ b/plone/app/contenttypes/tests/robot/test_folderlisting.robot
@@ -1,18 +1,13 @@
*** Settings ***
-Resource plone/app/robotframework/keywords.robot
-Resource plone/app/robotframework/saucelabs.robot
-Resource plone/app/robotframework/selenium.robot
+Resource plone/app/robotframework/browser.robot
Resource keywords.txt
Variables variables.py
-
Test Setup Run Keywords Setup Testcontent Plone test setup
Test Teardown Run keywords Plone test teardown
-*** Variables ***
-
*** Test cases ***
Scenario: Test folder listing view
@@ -101,7 +96,7 @@ Listing should list contained content in detail
the content area should contain this is a test document
the content area should contain Test News Item
the content area should contain this is a test news item
- Page Should Contain Element //img[@title="Test News Item"] 2
+ Get Element Count //img[@title="Test News Item"] == 2
the content area should contain Test Event
the content area should contain this is a test event
the content area should contain Test Collection
@@ -111,29 +106,29 @@ Listing should list contained content in detail
the content area should contain Test File
the content area should contain file.pdf
the content area should contain Test Image
- Page Should Contain Element //img[@title="Test Image"] 3
+ Get Element Count //img[@title="Test Image"] == 2
the content area should contain Test Album
the content area should contain Test Album Image 1
- Page Should Contain Element //img[@title="Test Album Image 1"] 2
+ Get Element Count //img[@title="Test Album Image 1"] == 2
the content area should contain Test Album Image 2
- Page Should Contain Element //img[@title="Test Album Image 2"] 2
+ Get Element Count //img[@title="Test Album Image 2"] == 2
the content area should contain Test Album Image 3
- Page Should Contain Element //img[@title="Test Album Image 3"] 2
+ Get Element Count //img[@title="Test Album Image 3"] == 2
the content area should contain Test Sub Album
the content area should contain Test Sub Album Image 1
- Page Should Contain Element //img[@title="Test Sub Album Image 1"] 1
+ Get Element Count //img[@title="Test Sub Album Image 1"] == 1
the content area should contain Test Sub Album Image 2
- Page Should Contain Element //img[@title="Test Sub Album Image 2"] 1
+ Get Element Count //img[@title="Test Sub Album Image 2"] == 1
the content area should contain Test Sub Album Image 3
- Page Should Contain Element //img[@title="Test Sub Album Image 3"] 1
+ Get Element Count //img[@title="Test Sub Album Image 3"] == 1
Album should list contained images and albums
the content area should contain Test Album Image 1
- Page Should Contain Element //img[@title="Test Album Image 1"] 2
+ Get Element Count //img[@title="Test Album Image 1"] == 1
the content area should contain Test Album Image 2
- Page Should Contain Element //img[@title="Test Album Image 2"] 2
+ Get Element Count //img[@title="Test Album Image 2"] == 1
the content area should contain Test Album Image 3
- Page Should Contain Element //img[@title="Test Album Image 3"] 2
+ Get Element Count //img[@title="Test Album Image 3"] == 1
the content area should contain Test Sub Album
@@ -159,7 +154,7 @@ Listing should list all content in detail
the content area should contain this is a test document
the content area should contain Test News Item
the content area should contain this is a test news item
- Page Should Contain Element //img[@title="Test News Item"] 2
+ Get Element Count //img[@title="Test News Item"] == 2
the content area should contain Test Event
the content area should contain this is a test event
the content area should contain Test Collection
@@ -169,39 +164,39 @@ Listing should list all content in detail
the content area should contain Test File
the content area should contain file.pdf
the content area should contain Test Image
- Page Should Contain Element //img[@title="Test Image"] 3
+ Get Element Count //img[@title="Test Image"] == 2
the content area should contain Test Album
the content area should contain Test Album Image 1
- Page Should Contain Element //img[@title="Test Album Image 1"] 2
+ Get Element Count //img[@title="Test Album Image 1"] == 2
the content area should contain Test Album Image 2
- Page Should Contain Element //img[@title="Test Album Image 2"] 2
+ Get Element Count //img[@title="Test Album Image 2"] == 2
the content area should contain Test Album Image 3
- Page Should Contain Element //img[@title="Test Album Image 3"] 2
+ Get Element Count //img[@title="Test Album Image 3"] == 2
the content area should contain Test Sub Album
the content area should contain Test Sub Album Image 1
- Page Should Contain Element //img[@title="Test Sub Album Image 1"] 2
+ Get Element Count //img[@title="Test Sub Album Image 1"] == 2
the content area should contain Test Sub Album Image 2
- Page Should Contain Element //img[@title="Test Sub Album Image 2"] 2
+ Get Element Count //img[@title="Test Sub Album Image 2"] == 2
the content area should contain Test Sub Album Image 3
- Page Should Contain Element //img[@title="Test Sub Album Image 3"] 2
+ Get Element Count //img[@title="Test Sub Album Image 3"] == 2
Album should list all images and albums
the content area should contain Test Image
- Page Should Contain Element //div[contains(@class, "card-image")]//img[@title="Test Image"] 1
+ Get Element Count //div[contains(@class, "card-image")]//img[@title="Test Image"] == 1
the content area should contain Test News Item
- Page Should Contain Element //div[contains(@class, "card-image")]//img[@title="Test News Item"] 1
+ Get Element Count //div[contains(@class, "card-image")]//img[@title="Test News Item"] == 1
the content area should contain Test Album Image 1
- Page Should Contain Element //div[contains(@class, "card-image")]//img[@title="Test Album Image 1"] 1
+ Get Element Count //div[contains(@class, "card-image")]//img[@title="Test Album Image 1"] == 1
the content area should contain Test Album Image 2
- Page Should Contain Element //div[contains(@class, "card-image")]//img[@title="Test Album Image 2"] 1
+ Get Element Count //div[contains(@class, "card-image")]//img[@title="Test Album Image 2"] == 1
the content area should contain Test Album Image 3
- Page Should Contain Element //div[contains(@class, "card-image")]//img[@title="Test Album Image 3"] 1
+ Get Element Count //div[contains(@class, "card-image")]//img[@title="Test Album Image 3"] == 1
the content area should contain Test Sub Album Image 1
- Page Should Contain Element //div[contains(@class, "card-image")]//img[@title="Test Sub Album Image 1"] 1
+ Get Element Count //div[contains(@class, "card-image")]//img[@title="Test Sub Album Image 1"] == 1
the content area should contain Test Sub Album Image 2
- Page Should Contain Element //div[contains(@class, "card-image")]//img[@title="Test Sub Album Image 2"] 1
+ Get Element Count //div[contains(@class, "card-image")]//img[@title="Test Sub Album Image 2"] == 1
the content area should contain Test Sub Album Image 3
- Page Should Contain Element //div[contains(@class, "card-image")]//img[@title="Test Sub Album Image 3"] 1
+ Get Element Count //div[contains(@class, "card-image")]//img[@title="Test Sub Album Image 3"] == 1
the content area should contain Test Album
the content area should contain Test Sub Album
@@ -230,8 +225,6 @@ I go to
I disable dropdown navigation
Go to ${PLONE_URL}/@@navigation-controlpanel
- Input Text name=form.widgets.navigation_depth 1
- Set Focus To Element css=#form-buttons-save
- Wait Until Element Is Visible css=#form-buttons-save
- Click Button Save
- Wait until page contains Changes saved
+ Fill Text css=[name="form.widgets.navigation_depth"] 1
+ Click "Save"
+ Get Text body contains Changes saved
diff --git a/plone/app/contenttypes/tests/test_event.py b/plone/app/contenttypes/tests/test_event.py
index 2ce969116..528059a99 100644
--- a/plone/app/contenttypes/tests/test_event.py
+++ b/plone/app/contenttypes/tests/test_event.py
@@ -91,24 +91,24 @@ def setUp(self):
def test_add_event(self):
self.browser.open(self.portal_url)
self.browser.getLink("Event").click()
- self.browser.getControl(
- name="form.widgets.IDublinCore.title"
- ).value = "My event"
- self.browser.getControl(
- name="form.widgets.IDublinCore.description"
- ).value = "This is my event."
- self.browser.getControl(
- name="form.widgets.IRichTextBehavior.text"
- ).value = "Lorem Ipsum"
- self.browser.getControl(
- name="form.widgets.IEventBasic.start"
- ).value = "2013-01-01"
- self.browser.getControl(
- name="form.widgets.IEventBasic.end"
- ).value = "2013-01-12"
- self.browser.getControl(
- name="form.widgets.IShortName.id"
- ).value = "my-special-event"
+ self.browser.getControl(name="form.widgets.IDublinCore.title").value = (
+ "My event"
+ )
+ self.browser.getControl(name="form.widgets.IDublinCore.description").value = (
+ "This is my event."
+ )
+ self.browser.getControl(name="form.widgets.IRichTextBehavior.text").value = (
+ "Lorem Ipsum"
+ )
+ self.browser.getControl(name="form.widgets.IEventBasic.start").value = (
+ "2013-01-01"
+ )
+ self.browser.getControl(name="form.widgets.IEventBasic.end").value = (
+ "2013-01-12"
+ )
+ self.browser.getControl(name="form.widgets.IShortName.id").value = (
+ "my-special-event"
+ )
self.browser.getControl("Save").click()
self.assertTrue(self.browser.url.endswith("my-special-event/view"))
diff --git a/plone/app/contenttypes/tests/test_folder.py b/plone/app/contenttypes/tests/test_folder.py
index 440eb6c2c..47c048f55 100644
--- a/plone/app/contenttypes/tests/test_folder.py
+++ b/plone/app/contenttypes/tests/test_folder.py
@@ -1,3 +1,5 @@
+from datetime import datetime
+from datetime import timedelta
from plone.app.contenttypes.browser.folder import FolderView
from plone.app.contenttypes.interfaces import IFolder
from plone.app.contenttypes.testing import ( # noqa
@@ -232,3 +234,26 @@ def test_list_item_wout_title(self):
# And also in tabular view
self.browser.open(self.folder_url + "/tabular_view")
self.assertIn("doc_wout_title", self.browser.contents)
+
+ def test_event_wout_location(self):
+ # deactivate "plone.eventlocation" from Event behaviors
+ event_fti = self.portal.portal_types.get("Event")
+ if not event_fti:
+ return
+ event_behaviors = list(event_fti.behaviors)
+ event_behaviors.remove("plone.eventlocation")
+ event_fti.behaviors = tuple(event_behaviors)
+
+ self.folder.invokeFactory(
+ "Event",
+ id="event_wout_location",
+ title="Event without location",
+ start=datetime.now() + timedelta(days=1),
+ )
+
+ import transaction
+
+ transaction.commit()
+
+ self.browser.open(self.folder_url + "/listing_view")
+ self.assertIn("Event without location", self.browser.contents)
diff --git a/plone/app/contenttypes/tests/test_link.py b/plone/app/contenttypes/tests/test_link.py
index dd306c274..dabdd9a81 100644
--- a/plone/app/contenttypes/tests/test_link.py
+++ b/plone/app/contenttypes/tests/test_link.py
@@ -1,4 +1,5 @@
from datetime import datetime
+from plone.app.contenttypes.browser.link_redirect_view import normalize_uid_from_path
from plone.app.contenttypes.interfaces import ILink
from plone.app.contenttypes.testing import ( # noqa
PLONE_APP_CONTENTTYPES_FUNCTIONAL_TESTING,
@@ -230,6 +231,117 @@ def test_ftp_type(self):
self.assertTrue(view())
self._assert_redirect(self.link.remoteUrl)
+ def test_normalize_uid_from_path(self):
+ url = None
+ uid, fragment = normalize_uid_from_path(url)
+ self.assertIsNone(uid)
+ self.assertIsNone(fragment)
+
+ url = "http://nohost"
+ uid, fragment = normalize_uid_from_path(url)
+ self.assertIsNone(uid)
+ self.assertIsNone(fragment)
+
+ url = "http://nohost/test1"
+ uid, fragment = normalize_uid_from_path(url)
+ self.assertIsNone(uid)
+ self.assertIsNone(fragment)
+
+ url = "http://nohost/test1/resolveuid"
+ uid, fragment = normalize_uid_from_path(url)
+ self.assertIsNone(uid)
+ self.assertIsNone(fragment)
+
+ url = "http://nohost/test1/resolveuid/"
+ uid, fragment = normalize_uid_from_path(url)
+ self.assertIsNone(uid)
+ self.assertIsNone(fragment)
+
+ url = "http://nohost/test1/resolveuid123/"
+ uid, fragment = normalize_uid_from_path(url)
+ self.assertIsNone(uid)
+ self.assertIsNone(fragment)
+
+ url = "http://nohost/test1/resolveuid/123"
+ uid, fragment = normalize_uid_from_path(url)
+ self.assertEqual(uid, "123")
+ self.assertIsNone(fragment)
+
+ url = "http://nohost/test1/resolveuid/123#my-id"
+ uid, fragment = normalize_uid_from_path(url)
+ self.assertEqual(uid, "123")
+ self.assertEqual(fragment, "#my-id")
+
+ url = "http://nohost/test1/resolveuid/123/"
+ uid, fragment = normalize_uid_from_path(url)
+ self.assertEqual(uid, "123")
+ self.assertIsNone(fragment)
+
+ url = "http://nohost/test1/resolveuid/123#my-id/"
+ uid, fragment = normalize_uid_from_path(url)
+ self.assertEqual(uid, "123")
+ self.assertEqual(fragment, "#my-id")
+
+ url = "http://nohost/test1/resolveuid/123/test"
+ uid, fragment = normalize_uid_from_path(url)
+ self.assertEqual(uid, "123")
+ self.assertIsNone(fragment)
+
+ url = "resolveuid/123"
+ uid, fragment = normalize_uid_from_path(url)
+ self.assertEqual(uid, "123")
+ self.assertIsNone(fragment)
+
+ url = "resolveuid/123#my-id"
+ uid, fragment = normalize_uid_from_path(url)
+ self.assertEqual(uid, "123")
+ self.assertEqual(fragment, "#my-id")
+
+ url = "resolveuid/123/"
+ uid, fragment = normalize_uid_from_path(url)
+ self.assertEqual(uid, "123")
+ self.assertIsNone(fragment)
+
+ url = "resolveuid/123#my-id/"
+ uid, fragment = normalize_uid_from_path(url)
+ self.assertEqual(uid, "123")
+ self.assertEqual(fragment, "#my-id")
+
+ url = "resolveuid/123/abc"
+ uid, fragment = normalize_uid_from_path(url)
+ self.assertEqual(uid, "123")
+ self.assertIsNone(fragment)
+
+ url = "/resolveuid/123"
+ uid, fragment = normalize_uid_from_path(url)
+ self.assertEqual(uid, "123")
+ self.assertIsNone(fragment)
+
+ url = "/resolveuid/123#my-id"
+ uid, fragment = normalize_uid_from_path(url)
+ self.assertEqual(uid, "123")
+ self.assertEqual(fragment, "#my-id")
+
+ url = "/resolveuid/123/"
+ uid, fragment = normalize_uid_from_path(url)
+ self.assertEqual(uid, "123")
+ self.assertIsNone(fragment)
+
+ url = "/resolveuid/123#my-id/"
+ uid, fragment = normalize_uid_from_path(url)
+ self.assertEqual(uid, "123")
+ self.assertEqual(fragment, "#my-id")
+
+ url = "/resolveuid/123/abc"
+ uid, fragment = normalize_uid_from_path(url)
+ self.assertEqual(uid, "123")
+ self.assertIsNone(fragment)
+
+ url = "/resolveUid/123#my-id"
+ uid, fragment = normalize_uid_from_path(url)
+ self.assertEqual(uid, "123")
+ self.assertEqual(fragment, "#my-id")
+
def _publish(self, obj):
portal_workflow = getToolByName(self.portal, "portal_workflow")
portal_workflow.doActionFor(obj, "publish")
@@ -267,15 +379,15 @@ def test_add_link(self):
self.browser.open(self.portal_url)
self.browser.getLink("Link").click()
self.browser.getControl(name="form.widgets.IDublinCore.title").value = "My link"
- self.browser.getControl(
- name="form.widgets.IDublinCore.description"
- ).value = "This is my link."
- self.browser.getControl(
- name="form.widgets.IShortName.id"
- ).value = "my-special-link"
- self.browser.getControl(
- name="form.widgets.remoteUrl.external"
- ).value = "https://plone.org"
+ self.browser.getControl(name="form.widgets.IDublinCore.description").value = (
+ "This is my link."
+ )
+ self.browser.getControl(name="form.widgets.IShortName.id").value = (
+ "my-special-link"
+ )
+ self.browser.getControl(name="form.widgets.remoteUrl.external").value = (
+ "https://plone.org"
+ )
self.browser.getControl("Save").click()
self.assertTrue(self.browser.url.endswith("my-special-link/view"))
@@ -374,5 +486,22 @@ def test_resolve_uid_to_absolute_target(self):
)
doc1 = self.portal["doc1"]
uid = IUUID(doc1)
+
+ portal_state = getMultiAdapter(
+ (self.link, self.request), name="plone_portal_state"
+ )
+ portal_url = portal_state.portal_url()
+
+ # check an internal link
self.link.remoteUrl = f"${{portal_url}}/resolveuid/{uid}"
- self.assertEqual(view.absolute_target_url(), "http://nohost/doc1")
+ self.assertEqual(view.absolute_target_url(), f"{portal_url}/doc1")
+
+ # check an internal link with fragment
+ self.link.remoteUrl = f"${{portal_url}}/resolveuid/{uid}#autotoc-item-autotoc-1"
+ self.assertEqual(
+ view.absolute_target_url(), f"{portal_url}/doc1#autotoc-item-autotoc-1"
+ )
+
+ # check not resolvable uid
+ self.link.remoteUrl = "/resolveuid/abc123"
+ self.assertEqual(view.absolute_target_url(), "/resolveuid/abc123")
diff --git a/plone/app/contenttypes/tests/test_news_item.py b/plone/app/contenttypes/tests/test_news_item.py
index 9bab672be..09ff40def 100644
--- a/plone/app/contenttypes/tests/test_news_item.py
+++ b/plone/app/contenttypes/tests/test_news_item.py
@@ -112,16 +112,16 @@ def setUp(self):
def test_add_news_item(self):
self.browser.open(self.portal_url)
self.browser.getLink("News Item").click()
- self.browser.getControl(
- name="form.widgets.IDublinCore.title"
- ).value = "My news item"
- self.browser.getControl(
- name="form.widgets.IDublinCore.description"
- ).value = "This is my news item."
+ self.browser.getControl(name="form.widgets.IDublinCore.title").value = (
+ "My news item"
+ )
+ self.browser.getControl(name="form.widgets.IDublinCore.description").value = (
+ "This is my news item."
+ )
self.browser.getControl(name="form.widgets.IShortName.id").value = ""
- self.browser.getControl(
- name="form.widgets.IRichTextBehavior.text"
- ).value = "Lorem Ipsum"
+ self.browser.getControl(name="form.widgets.IRichTextBehavior.text").value = (
+ "Lorem Ipsum"
+ )
self.browser.getControl("Save").click()
self.assertTrue(self.browser.url.endswith("my-news-item/view"))
@@ -132,12 +132,12 @@ def test_add_news_item(self):
def test_add_news_item_with_shortname(self):
self.browser.open(self.portal_url)
self.browser.getLink("News Item").click()
- self.browser.getControl(
- name="form.widgets.IDublinCore.title"
- ).value = "My news item"
- self.browser.getControl(
- name="form.widgets.IShortName.id"
- ).value = "my-special-news"
+ self.browser.getControl(name="form.widgets.IDublinCore.title").value = (
+ "My news item"
+ )
+ self.browser.getControl(name="form.widgets.IShortName.id").value = (
+ "my-special-news"
+ )
self.browser.getControl("Save").click()
self.assertTrue(self.browser.url.endswith("my-special-news/view"))
diff --git a/pyproject.toml b/pyproject.toml
index e4468843b..35e47cbbe 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,6 +1,9 @@
# Generated from:
-# https://github.com/plone/meta/tree/master/config/default
+# https://github.com/plone/meta/tree/main/config/default
# See the inline comments on how to expand/tweak this configuration file
+[build-system]
+requires = ["setuptools>=68.2"]
+
[tool.towncrier]
directory = "news/"
filename = "CHANGES.rst"
@@ -37,14 +40,38 @@ directory = "tests"
name = "Tests"
showcontent = true
+##
+# Add extra configuration options in .meta.toml:
+# [pyproject]
+# towncrier_extra_lines = """
+# extra_configuration
+# """
+##
+
[tool.isort]
profile = "plone"
+##
+# Add extra configuration options in .meta.toml:
+# [pyproject]
+# isort_extra_lines = """
+# extra_configuration
+# """
+##
+
[tool.black]
target-version = ["py38"]
+##
+# Add extra configuration options in .meta.toml:
+# [pyproject]
+# black_extra_lines = """
+# extra_configuration
+# """
+##
+
[tool.codespell]
-ignore-words-list = "discreet,oder,ist,crate"
+ignore-words-list = "discreet,assertin,oder,ist,crate"
skip = "*.po,"
##
# Add extra configuration options in .meta.toml:
@@ -102,19 +129,20 @@ ignore-packages = ['ZServer', 'plone.app.event', 'Products.CMFPlone',]
# "gitpython = ['git']",
# "pygithub = ['github']",
# ]
-# """
##
[tool.check-manifest]
ignore = [
".editorconfig",
+ ".flake8",
".meta.toml",
".pre-commit-config.yaml",
- "tox.ini",
- ".flake8",
+ "dependabot.yml",
"mx.ini",
+ "tox.ini",
]
+
##
# Add extra configuration options in .meta.toml:
# [pyproject]
@@ -122,6 +150,11 @@ ignore = [
# "*.map.js",
# "*.pyc",
# """
+# check_manifest_extra_lines = """
+# ignore-bad-ideas = [
+# "some/test/file/PKG-INFO",
+# ]
+# """
##
diff --git a/setup.py b/setup.py
index 03e62fdf0..2b47eed8e 100644
--- a/setup.py
+++ b/setup.py
@@ -4,7 +4,7 @@
import os
-version = "3.0.3"
+version = "4.0.1.dev0"
def read(*rnames):
@@ -24,16 +24,15 @@ def read(*rnames):
"Development Status :: 5 - Production/Stable",
"Environment :: Web Environment",
"Framework :: Plone",
- "Framework :: Plone :: 6.0",
+ "Framework :: Plone :: 6.1",
"Framework :: Plone :: Core",
"Framework :: Zope :: 5",
"License :: OSI Approved :: GNU General Public License v2 (GPLv2)",
"Operating System :: OS Independent",
"Programming Language :: Python",
- "Programming Language :: Python :: 3.8",
- "Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
+ "Programming Language :: Python :: 3.12",
],
keywords="plone content types dexterity",
author="Plone Foundation",
@@ -44,7 +43,7 @@ def read(*rnames):
namespace_packages=["plone", "plone.app"],
include_package_data=True,
zip_safe=False,
- python_requires=">=3.8",
+ python_requires=">=3.10",
install_requires=[
"setuptools",
"plone.app.contentmenu",
@@ -59,7 +58,6 @@ def read(*rnames):
"plone.app.lockingbehavior",
"plone.behavior >= 1.3.0",
"plone.app.z3cform>=1.1.0",
- "zope.deprecation",
"plone.base",
"Products.BTreeFolder2",
"Products.GenericSetup",
@@ -72,7 +70,6 @@ def read(*rnames):
"plone.autoform",
"plone.event",
"plone.folder",
- "plone.i18n",
"plone.indexer",
"plone.memoize",
"plone.portlets",
@@ -81,7 +78,7 @@ def read(*rnames):
"plone.supermodel",
"plone.z3cform",
"z3c.form",
- "zope.contentprovider",
+ "Zope",
],
extras_require={
"test": [
@@ -91,7 +88,6 @@ def read(*rnames):
"plone.testing",
"plone.browserlayer",
"plone.uuid",
- "zope.viewlet",
"robotsuite",
],
},
diff --git a/tox.ini b/tox.ini
index 030fd7492..c0b0ad2bf 100644
--- a/tox.ini
+++ b/tox.ini
@@ -1,5 +1,5 @@
# Generated from:
-# https://github.com/plone/meta/tree/master/config/default
+# https://github.com/plone/meta/tree/main/config/default
# See the inline comments on how to expand/tweak this configuration file
[tox]
# We need 4.4.0 for constrain_package_deps.
@@ -32,6 +32,21 @@ commands =
echo "Unrecognized environment name {envname}"
false
+##
+# Add extra configuration options in .meta.toml:
+# [tox]
+# testenv_options = """
+# basepython = /usr/bin/python3.8
+# """
+##
+
+[testenv:init]
+description = Prepare environment
+skip_install = true
+commands =
+ echo "Initial setup complete"
+
+
[testenv:format]
description = automatically reformat code
skip_install = true
@@ -56,9 +71,9 @@ description = check if the package defines all its dependencies
skip_install = true
deps =
build
- z3c.dependencychecker==2.11
+ z3c.dependencychecker==2.14.3
commands =
- python -m build --sdist --no-isolation
+ python -m build --sdist
dependencychecker
[testenv:dependencies-graph]
@@ -77,11 +92,35 @@ description = run the distribution tests
use_develop = true
skip_install = false
constrain_package_deps = true
-set_env = ROBOT_BROWSER=headlesschrome
+set_env =
+ ROBOT_BROWSER=headlesschrome
+
+##
+# Specify extra test environment variables in .meta.toml:
+# [tox]
+# test_environment_variables = """
+# PIP_EXTRA_INDEX_URL=https://my-pypi.my-server.com/
+# """
+#
+# Set constrain_package_deps .meta.toml:
+# [tox]
+# constrain_package_deps = "false"
+##
deps =
zope.testrunner
- -c https://dist.plone.org/release/6.0-dev/constraints.txt
+ -c https://dist.plone.org/release/6.1-dev/constraints.txt
+
+##
+# Specify additional deps in .meta.toml:
+# [tox]
+# test_deps_additional = "-esources/plonegovbr.portal_base[test]"
+#
+# Specify a custom constraints file in .meta.toml:
+# [tox]
+# constraints_file = "https://my-server.com/constraints.txt"
+##
commands =
+ rfbrowser init
zope-testrunner --all --test-path={toxinidir} -s plone.app.contenttypes {posargs}
extras =
test
@@ -100,14 +139,27 @@ description = get a test coverage report
use_develop = true
skip_install = false
constrain_package_deps = true
-set_env = ROBOT_BROWSER=headlesschrome
+set_env =
+ ROBOT_BROWSER=headlesschrome
+
+##
+# Specify extra test environment variables in .meta.toml:
+# [tox]
+# test_environment_variables = """
+# PIP_EXTRA_INDEX_URL=https://my-pypi.my-server.com/
+# """
+##
deps =
coverage
zope.testrunner
- -c https://dist.plone.org/release/6.0-dev/constraints.txt
+ -c https://dist.plone.org/release/6.1-dev/constraints.txt
+
commands =
+ rfbrowser init
coverage run --branch --source plone.app.contenttypes {envbindir}/zope-testrunner --quiet --all --test-path={toxinidir} -s plone.app.contenttypes {posargs}
coverage report -m --format markdown
+ coverage xml
+ coverage html
extras =
test
@@ -119,25 +171,39 @@ deps =
twine
build
towncrier
- -c https://dist.plone.org/release/6.0-dev/constraints.txt
+ -c https://dist.plone.org/release/6.1-dev/constraints.txt
+
commands =
# fake version to not have to install the package
# we build the change log as news entries might break
# the README that is displayed on PyPI
towncrier build --version=100.0.0 --yes
- python -m build --sdist --no-isolation
+ python -m build --sdist
twine check dist/*
[testenv:circular]
description = ensure there are no cyclic dependencies
use_develop = true
skip_install = false
+# Here we must always constrain the package deps to what is already installed,
+# otherwise we simply get the latest from PyPI, which may not work.
+constrain_package_deps = true
+set_env =
+
+##
+# Specify extra test environment variables in .meta.toml:
+# [tox]
+# test_environment_variables = """
+# PIP_EXTRA_INDEX_URL=https://my-pypi.my-server.com/
+# """
+##
allowlist_externals =
sh
deps =
pipdeptree
pipforester
- -c https://dist.plone.org/release/6.0-dev/constraints.txt
+ -c https://dist.plone.org/release/6.1-dev/constraints.txt
+
commands =
# Generate the full dependency tree
sh -c 'pipdeptree -j > forest.json'
@@ -151,6 +217,6 @@ commands =
# Add extra configuration options in .meta.toml:
# [tox]
# extra_lines = """
-# my_other_environment
+# _your own configuration lines_
# """
##